major rework of reference handling

This commit is contained in:
Avi Zimmerman
2021-01-19 00:18:30 +02:00
parent 63a53be42a
commit 1f7d60b390
79 changed files with 1239 additions and 800 deletions

View File

@@ -12,6 +12,8 @@ As the latter requires published tags, see godoc.org for the latest documentatio
**This library has not been thoroughly tested and as such is not recommended for mission critical applications yet. If you'd like to try it out and encounter any bugs, feel free to open an Issue or PR. For more information see the [Contributing](#contributing) section.**
Recently almost all memory handling has been moved into the bindings. Some documentation may still reflect the original need to Unref resources, but in most situations that is not the case anymore.
## Requirements
For building applications with this library you need the following:
@@ -53,7 +55,6 @@ func main() {
// Create a main loop. This is only required when utilizing signals via the bindings.
// In this example, the AddWatch on the pipeline bus requires iterating on the main loop.
mainLoop := glib.NewMainLoop(glib.MainContextDefault(), false)
defer mainLoop.Unref()
// Build a pipeline string from the cli arguments
pipelineString := strings.Join(os.Args[1:], " ")
@@ -90,11 +91,6 @@ func main() {
// Block and iterate on the main loop
mainLoop.Run()
// Destroy the pipeline
if err := pipeline.Destroy(); err != nil {
fmt.Println("Error destroying the pipeline:", err)
}
}
```

View File

@@ -55,7 +55,6 @@ func createPipeline() (*gst.Pipeline, error) {
if sample == nil {
return gst.FlowEOS
}
defer sample.Unref()
// Retrieve the buffer from the sample
buffer := sample.GetBuffer()
@@ -89,7 +88,6 @@ func createPipeline() (*gst.Pipeline, error) {
}
func handleMessage(msg *gst.Message) error {
defer msg.Unref() // Messages are a good candidate for trying out runtime finalizers
switch msg.Type() {
case gst.MessageEOS:
@@ -103,8 +101,6 @@ func handleMessage(msg *gst.Message) error {
func mainLoop(pipeline *gst.Pipeline) error {
defer pipeline.Destroy() // Will stop and unref the pipeline when this function returns
// Start the pipeline
pipeline.SetState(gst.StatePlaying)

View File

@@ -7,6 +7,7 @@ import (
"image/color"
"time"
"github.com/tinyzimmer/go-glib/glib"
"github.com/tinyzimmer/go-gst/examples"
"github.com/tinyzimmer/go-gst/gst"
"github.com/tinyzimmer/go-gst/gst/app"
@@ -88,7 +89,7 @@ func createPipeline() (*gst.Pipeline, error) {
// There are convenience wrappers for building buffers directly from byte sequences as
// well.
buffer.Map(gst.MapWrite).WriteData(pixels)
defer buffer.Unmap()
buffer.Unmap()
// Push the buffer onto the pipeline.
self.PushBuffer(buffer)
@@ -115,8 +116,6 @@ func produceImageFrame(c color.Color) []uint8 {
}
func handleMessage(msg *gst.Message) error {
defer msg.Unref() // Messages are a good candidate for trying out runtime finalizers
switch msg.Type() {
case gst.MessageEOS:
return app.ErrEOS
@@ -127,41 +126,42 @@ func handleMessage(msg *gst.Message) error {
}
return gerr
}
return nil
}
func mainLoop(pipeline *gst.Pipeline) error {
defer pipeline.Destroy() // Will stop and unref the pipeline when this function returns
func mainLoop(loop *glib.MainLoop, pipeline *gst.Pipeline) error {
// Start the pipeline
// Due to recent changes in the pipeline - the finalizers might fire on the pipeline
// prematurely when it's passed between scopes. So when you do this, it is safer to
// take a reference that you dispose of when you are done.
pipeline.Ref()
defer pipeline.Unref()
pipeline.SetState(gst.StatePlaying)
// Retrieve the bus from the pipeline
bus := pipeline.GetPipelineBus()
// Loop over messsages from the pipeline
for {
msg := bus.TimedPop(time.Duration(-1))
if msg == nil {
break
}
// Retrieve the bus from the pipeline and add a watch function
pipeline.GetPipelineBus().AddWatch(func(msg *gst.Message) bool {
if err := handleMessage(msg); err != nil {
return err
}
fmt.Println(err)
loop.Quit()
return false
}
return true
})
loop.Run()
return nil
}
func main() {
examples.Run(func() error {
examples.RunLoop(func(loop *glib.MainLoop) error {
var pipeline *gst.Pipeline
var err error
if pipeline, err = createPipeline(); err != nil {
return err
}
return mainLoop(pipeline)
return mainLoop(loop, pipeline)
})
}

View File

@@ -10,8 +10,6 @@ import (
func Run(f func() error) {
mainLoop := glib.NewMainLoop(glib.MainContextDefault(), false)
defer mainLoop.Unref()
go func() {
if err := f(); err != nil {
fmt.Println("ERROR!", err)
@@ -26,7 +24,6 @@ func Run(f func() error) {
// The main loop itself is passed to the function for more control over exiting.
func RunLoop(f func(*glib.MainLoop) error) {
mainLoop := glib.NewMainLoop(glib.MainContextDefault(), false)
defer mainLoop.Unref()
if err := f(mainLoop); err != nil {
fmt.Println("ERROR!", err)

View File

@@ -84,7 +84,6 @@ func mainLoop(loop *glib.MainLoop, pipeline *gst.Pipeline) error {
switch msg.Type() {
case gst.MessageEOS:
fmt.Println("Got EOS message")
pipeline.Destroy()
loop.Quit()
default:
fmt.Println(msg)

View File

@@ -156,8 +156,6 @@ func buildPipeline() (*gst.Pipeline, error) {
func runPipeline(loop *glib.MainLoop, pipeline *gst.Pipeline) error {
// Start the pipeline
pipeline.SetState(gst.StatePlaying)
// Stop and cleanup the pipeline when we exit
defer pipeline.Destroy()
// Add a message watch to the bus to quit on any error
pipeline.GetPipelineBus().AddWatch(func(msg *gst.Message) bool {

View File

@@ -99,13 +99,9 @@ func runPipeline(loop *glib.MainLoop) error {
// Remove the watch function from the bus.
// Again: There can always only be one watch function.
// Thus we don't have to tell him which function to remove.
// Thus we don't have to tell it which function to remove.
bus.RemoveWatch()
// Unref the pipeline because we are done with it. The combination of setting
// the state to NULL and unreffing is the semantic equivalent to calling Destroy().
pipeline.Unref()
return nil
}

View File

@@ -40,7 +40,6 @@ func encodeGif(mainLoop *glib.MainLoop) error {
if err != nil {
return err
}
defer pipeline.Destroy()
// Create a filesrc and a decodebin element for the pipeline.
elements, err := gst.NewElementMany("filesrc", "decodebin")
@@ -69,7 +68,7 @@ func encodeGif(mainLoop *glib.MainLoop) error {
// The Bus PostError method is a convenience wrapper for building rich messages and sending them
// down the pipeline. The below call will create a new error message, populate the debug info
// with a stack trace from this goroutine, and add additional details from the provided error.
pipeline.GetPipelineBus().PostError(self, "Failed to build elements for the linked pipeline", err)
self.ErrorMessage(gst.DomainLibrary, gst.LibraryErrorFailed, "Failed to build elements for the linked pipeline", err.Error())
return
}
@@ -113,7 +112,7 @@ func encodeGif(mainLoop *glib.MainLoop) error {
// use this value to calculate the total number of frames we expect to produce.
query := gst.NewDurationQuery(gst.FormatTime)
if ok := self.Query(query); !ok {
pipeline.GetPipelineBus().PostError(self, "Failed to query video duration from decodebin", nil)
self.ErrorMessage(gst.DomainLibrary, gst.LibraryErrorFailed, "Failed to query video duration from decodebin", err.Error())
return
}
@@ -174,7 +173,7 @@ func encodeGif(mainLoop *glib.MainLoop) error {
// We can get an io.Reader directly from the buffer.
img, err := jpeg.Decode(buffer.Reader())
if err != nil {
pipeline.GetPipelineBus().PostError(sink, "Error decoding jpeg frame", err)
self.ErrorMessage(gst.DomainLibrary, gst.LibraryErrorFailed, "Error decoding jpeg frame", err.Error())
return gst.FlowError
}

View File

@@ -54,10 +54,7 @@ func runPipeline(mainLoop *glib.MainLoop) error {
pipeline.SetState(gst.StatePlaying)
// Block on the main loop
mainLoop.Run()
// Destroy the pipeline
return pipeline.Destroy()
return mainLoop.RunError()
}
func main() {

View File

@@ -96,7 +96,7 @@ func padProbes(mainLoop *glib.MainLoop) error {
}
}
return pipeline.Destroy()
return nil
}
func handleMessage(msg *gst.Message) error {

View File

@@ -83,9 +83,7 @@ func playbin(mainLoop *glib.MainLoop) error {
return true
})
mainLoop.Run()
return playbin.SetState(gst.StateNull)
return mainLoop.RunError()
}
func main() {

View File

@@ -96,7 +96,7 @@ func queries(mainLoop *glib.MainLoop) error {
bus.RemoveWatch()
return pipeline.Destroy()
return nil
}
func main() {

View File

@@ -38,7 +38,6 @@ func tagsetter() error {
if err != nil {
return err
}
defer pipeline.Destroy()
// Query the pipeline for elements implementing the GstTagsetter interface.
// In our case, this will return the flacenc element.

View File

@@ -34,7 +34,6 @@ func tagsetter(mainLoop *glib.MainLoop) error {
if err != nil {
return err
}
defer pipeline.Destroy()
src, err := gst.NewElement("filesrc")
if err != nil {

2
go.mod
View File

@@ -4,5 +4,5 @@ go 1.15
require (
github.com/mattn/go-pointer v0.0.1
github.com/tinyzimmer/go-glib v0.0.11
github.com/tinyzimmer/go-glib v0.0.15
)

8
go.sum
View File

@@ -1,4 +1,8 @@
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/tinyzimmer/go-glib v0.0.11 h1:+X15JtyglmBhiLu5KXHWxcxhypyc/CEqW+SIFmjZ110=
github.com/tinyzimmer/go-glib v0.0.11/go.mod h1:zy2cs6eXSTtqqYrv9/UgYMDfr4pWKuYPSzwX87cBGX4=
github.com/tinyzimmer/go-glib v0.0.12 h1:3illkvxCT71DT12tix1iGl+jkA/JdZxtcj0z3V9Aevo=
github.com/tinyzimmer/go-glib v0.0.12/go.mod h1:zy2cs6eXSTtqqYrv9/UgYMDfr4pWKuYPSzwX87cBGX4=
github.com/tinyzimmer/go-glib v0.0.14 h1:Axk3eBfBqaCOvBEXwuqNVJ3YAL41R6GFpj9IlYkPZ+w=
github.com/tinyzimmer/go-glib v0.0.14/go.mod h1:zy2cs6eXSTtqqYrv9/UgYMDfr4pWKuYPSzwX87cBGX4=
github.com/tinyzimmer/go-glib v0.0.15 h1:F6Ht4OJevy5KsDx/ecO73NIk5OVte3ghdYdEnwDWaPg=
github.com/tinyzimmer/go-glib v0.0.15/go.mod h1:zy2cs6eXSTtqqYrv9/UgYMDfr4pWKuYPSzwX87cBGX4=

View File

@@ -30,11 +30,11 @@ func getSrcCbsFromPtr(userData C.gpointer) *SourceCallbacks {
}
func wrapCSink(sink *C.GstAppSink) *Sink {
return wrapAppSink(gst.FromGstElementUnsafe(unsafe.Pointer(sink)))
return wrapAppSink(gst.FromGstElementUnsafeNone(unsafe.Pointer(sink)))
}
func wrapCSource(src *C.GstAppSrc) *Source {
return wrapAppSrc(gst.FromGstElementUnsafe(unsafe.Pointer(src)))
return wrapAppSrc(gst.FromGstElementUnsafeNone(unsafe.Pointer(src)))
}
//export goNeedDataCb

View File

@@ -73,7 +73,7 @@ func (a *Sink) GetCaps() *gst.Caps {
if caps == nil {
return nil
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// GetDrop checks if appsink will drop old buffers when the maximum amount of queued buffers is reached.
@@ -118,7 +118,7 @@ func (a *Sink) PullPreroll() *gst.Sample {
if smpl == nil {
return nil
}
return gst.FromGstSampleUnsafe(unsafe.Pointer(smpl))
return gst.FromGstSampleUnsafeFull(unsafe.Pointer(smpl))
}
// PullSample blocks until a sample or EOS becomes available or the appsink element is set to the READY/NULL state.
@@ -133,7 +133,7 @@ func (a *Sink) PullSample() *gst.Sample {
if smpl == nil {
return nil
}
return gst.FromGstSampleUnsafe(unsafe.Pointer(smpl))
return gst.FromGstSampleUnsafeFull(unsafe.Pointer(smpl))
}
// SetBufferListSupport instructs appsink to enable or disable buffer list support.
@@ -211,7 +211,7 @@ func (a *Sink) TryPullPreroll(timeout time.Duration) *gst.Sample {
if smpl == nil {
return nil
}
return gst.FromGstSampleUnsafe(unsafe.Pointer(smpl))
return gst.FromGstSampleUnsafeFull(unsafe.Pointer(smpl))
}
// TryPullSample blocks until a sample or EOS becomes available or the appsink element is set to the READY/NULL state or the timeout expires.
@@ -227,5 +227,5 @@ func (a *Sink) TryPullSample(timeout time.Duration) *gst.Sample {
if smpl == nil {
return nil
}
return gst.FromGstSampleUnsafe(unsafe.Pointer(smpl))
return gst.FromGstSampleUnsafeFull(unsafe.Pointer(smpl))
}

View File

@@ -80,7 +80,7 @@ func (a *Source) GetCaps() *gst.Caps {
if caps == nil {
return nil
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// GetCurrentLevelBytes gets the number of currently queued bytes inside appsrc.
@@ -131,7 +131,7 @@ func (a *Source) GetStreamType() StreamType {
func (a *Source) PushBuffer(buf *gst.Buffer) gst.FlowReturn {
ret := C.gst_app_src_push_buffer(
(*C.GstAppSrc)(a.Instance()),
(*C.GstBuffer)(unsafe.Pointer(buf.Instance())),
(*C.GstBuffer)(unsafe.Pointer(buf.Ref().Instance())),
)
return gst.FlowReturn(ret)
}
@@ -142,7 +142,7 @@ func (a *Source) PushBuffer(buf *gst.Buffer) gst.FlowReturn {
// When the block property is TRUE, this function can block until free space becomes available in the queue.
func (a *Source) PushBufferList(bufList *gst.BufferList) gst.FlowReturn {
return gst.FlowReturn(C.gst_app_src_push_buffer_list(
a.Instance(), (*C.GstBufferList)(unsafe.Pointer(bufList.Instance())),
a.Instance(), (*C.GstBufferList)(unsafe.Pointer(bufList.Ref().Instance())),
))
}

View File

@@ -37,7 +37,7 @@ func ToGstBaseSink(obj interface{}) *GstBaseSink {
// wrapGstBaseSink wraps the given unsafe.Pointer in a GstBaseSink instance.
func wrapGstBaseSink(obj *C.GstBaseSink) *GstBaseSink {
return &GstBaseSink{gst.FromGstElementUnsafe(unsafe.Pointer(obj))}
return &GstBaseSink{gst.FromGstElementUnsafeNone(unsafe.Pointer(obj))}
}
// Instance returns the underlying C GstBaseSrc instance
@@ -98,7 +98,7 @@ func (g *GstBaseSink) GetLastSample() *gst.Sample {
if sample == nil {
return nil
}
return gst.FromGstSampleUnsafe(unsafe.Pointer(sample))
return gst.FromGstSampleUnsafeFull(unsafe.Pointer(sample))
}
// GetLatency gets the currently configured latency.

View File

@@ -26,7 +26,7 @@ func goGstBaseSinkEvent(sink *C.GstBaseSink, event *C.GstEvent) C.gboolean {
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
Event(self *GstBaseSink, event *gst.Event) bool
})
return gboolean(iface.Event(wrapGstBaseSink(sink), gst.FromGstEventUnsafe(unsafe.Pointer(event))))
return gboolean(iface.Event(wrapGstBaseSink(sink), gst.FromGstEventUnsafeNone(unsafe.Pointer(event))))
}
//export goGstBaseSinkFixate
@@ -34,7 +34,7 @@ func goGstBaseSinkFixate(sink *C.GstBaseSink, caps *C.GstCaps) *C.GstCaps {
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
Fixate(self *GstBaseSink, caps *gst.Caps) *gst.Caps
})
fixated := iface.Fixate(wrapGstBaseSink(sink), gst.FromGstCapsUnsafe(unsafe.Pointer(caps)))
fixated := iface.Fixate(wrapGstBaseSink(sink), gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps)))
if fixated == nil {
return nil
}
@@ -46,7 +46,7 @@ func goGstBaseSinkGetCaps(sink *C.GstBaseSink, filter *C.GstCaps) *C.GstCaps {
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
GetCaps(self *GstBaseSink, filter *gst.Caps) *gst.Caps
})
filtered := iface.GetCaps(wrapGstBaseSink(sink), gst.FromGstCapsUnsafe(unsafe.Pointer(filter)))
filtered := iface.GetCaps(wrapGstBaseSink(sink), gst.FromGstCapsUnsafeNone(unsafe.Pointer(filter)))
if filtered == nil {
return nil
}
@@ -58,7 +58,7 @@ func goGstBaseSinkGetTimes(sink *C.GstBaseSink, buf *C.GstBuffer, start, end *C.
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
GetTimes(self *GstBaseSink, buffer *gst.Buffer) (start, end time.Duration)
})
retStart, retEnd := iface.GetTimes(wrapGstBaseSink(sink), gst.FromGstBufferUnsafe(unsafe.Pointer(buf)))
retStart, retEnd := iface.GetTimes(wrapGstBaseSink(sink), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf)))
*start = C.GstClockTime(retStart.Nanoseconds())
*end = C.GstClockTime(retEnd.Nanoseconds())
}
@@ -68,7 +68,7 @@ func goGstBaseSinkPrepare(sink *C.GstBaseSink, buf *C.GstBuffer) C.GstFlowReturn
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
Prepare(self *GstBaseSink, buffer *gst.Buffer) gst.FlowReturn
})
return C.GstFlowReturn(iface.Prepare(wrapGstBaseSink(sink), gst.FromGstBufferUnsafe(unsafe.Pointer(buf))))
return C.GstFlowReturn(iface.Prepare(wrapGstBaseSink(sink), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf))))
}
//export goGstBaseSinkPrepareList
@@ -76,7 +76,7 @@ func goGstBaseSinkPrepareList(sink *C.GstBaseSink, list *C.GstBufferList) C.GstF
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
PrepareList(self *GstBaseSink, bufferList *gst.BufferList) gst.FlowReturn
})
return C.GstFlowReturn(iface.PrepareList(wrapGstBaseSink(sink), gst.FromGstBufferListUnsafe(unsafe.Pointer(list))))
return C.GstFlowReturn(iface.PrepareList(wrapGstBaseSink(sink), gst.FromGstBufferListUnsafeNone(unsafe.Pointer(list))))
}
//export goGstBaseSinkPreroll
@@ -84,7 +84,7 @@ func goGstBaseSinkPreroll(sink *C.GstBaseSink, buf *C.GstBuffer) C.GstFlowReturn
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
Preroll(self *GstBaseSink, buffer *gst.Buffer) gst.FlowReturn
})
return C.GstFlowReturn(iface.Preroll(wrapGstBaseSink(sink), gst.FromGstBufferUnsafe(unsafe.Pointer(buf))))
return C.GstFlowReturn(iface.Preroll(wrapGstBaseSink(sink), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf))))
}
//export goGstBaseSinkProposeAllocation
@@ -92,7 +92,7 @@ func goGstBaseSinkProposeAllocation(sink *C.GstBaseSink, query *C.GstQuery) C.gb
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
ProposeAllocation(self *GstBaseSink, query *gst.Query) bool
})
return gboolean(iface.ProposeAllocation(wrapGstBaseSink(sink), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(iface.ProposeAllocation(wrapGstBaseSink(sink), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}
//export goGstBaseSinkQuery
@@ -100,7 +100,7 @@ func goGstBaseSinkQuery(sink *C.GstBaseSink, query *C.GstQuery) C.gboolean {
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
Query(self *GstBaseSink, query *gst.Query) bool
})
return gboolean(iface.Query(wrapGstBaseSink(sink), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(iface.Query(wrapGstBaseSink(sink), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}
//export goGstBaseSinkRender
@@ -108,7 +108,7 @@ func goGstBaseSinkRender(sink *C.GstBaseSink, buf *C.GstBuffer) C.GstFlowReturn
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
Render(self *GstBaseSink, buffer *gst.Buffer) gst.FlowReturn
})
return C.GstFlowReturn(iface.Render(wrapGstBaseSink(sink), gst.FromGstBufferUnsafe(unsafe.Pointer(buf))))
return C.GstFlowReturn(iface.Render(wrapGstBaseSink(sink), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf))))
}
//export goGstBaseSinkRenderList
@@ -116,7 +116,7 @@ func goGstBaseSinkRenderList(sink *C.GstBaseSink, buf *C.GstBufferList) C.GstFlo
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
RenderList(self *GstBaseSink, bufferList *gst.BufferList) gst.FlowReturn
})
return C.GstFlowReturn(iface.RenderList(wrapGstBaseSink(sink), gst.FromGstBufferListUnsafe(unsafe.Pointer(buf))))
return C.GstFlowReturn(iface.RenderList(wrapGstBaseSink(sink), gst.FromGstBufferListUnsafeNone(unsafe.Pointer(buf))))
}
//export goGstBaseSinkSetCaps
@@ -124,7 +124,7 @@ func goGstBaseSinkSetCaps(sink *C.GstBaseSink, caps *C.GstCaps) C.gboolean {
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
SetCaps(self *GstBaseSink, caps *gst.Caps) bool
})
return gboolean(iface.SetCaps(wrapGstBaseSink(sink), gst.FromGstCapsUnsafe(unsafe.Pointer(caps))))
return gboolean(iface.SetCaps(wrapGstBaseSink(sink), gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps))))
}
//export goGstBaseSinkStart
@@ -164,5 +164,5 @@ func goGstBaseSinkWaitEvent(sink *C.GstBaseSink, event *C.GstEvent) C.GstFlowRet
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(sink)).(interface {
WaitEvent(self *GstBaseSink, event *gst.Event) gst.FlowReturn
})
return C.GstFlowReturn(iface.WaitEvent(wrapGstBaseSink(sink), gst.FromGstEventUnsafe(unsafe.Pointer(event))))
return C.GstFlowReturn(iface.WaitEvent(wrapGstBaseSink(sink), gst.FromGstEventUnsafeNone(unsafe.Pointer(event))))
}

View File

@@ -30,7 +30,7 @@ func ToGstBaseSrc(obj interface{}) *GstBaseSrc {
// wrapGstBaseSrc wraps the given unsafe.Pointer in a GstBaseSrc instance.
func wrapGstBaseSrc(obj *C.GstBaseSrc) *GstBaseSrc {
return &GstBaseSrc{gst.FromGstElementUnsafe(unsafe.Pointer(obj))}
return &GstBaseSrc{gst.FromGstElementUnsafeNone(unsafe.Pointer(obj))}
}
// Instance returns the underlying C GstBaseSrc instance
@@ -43,7 +43,10 @@ func (g *GstBaseSrc) GetAllocator() (*gst.Allocator, *gst.AllocationParams) {
var allocParams C.GstAllocationParams
var allocator *C.GstAllocator
C.gst_base_src_get_allocator(g.Instance(), &allocator, &allocParams)
return gst.FromGstAllocatorUnsafe(unsafe.Pointer(allocator)), gst.FromGstAllocationParamsUnsafe(unsafe.Pointer(&allocParams))
if allocator == nil {
return nil, nil
}
return gst.FromGstAllocatorUnsafeFull(unsafe.Pointer(allocator)), gst.FromGstAllocationParamsUnsafe(unsafe.Pointer(&allocParams))
}
// GetBlocksize returns the number of bytes that the source will push out with each buffer.
@@ -51,7 +54,11 @@ func (g *GstBaseSrc) GetBlocksize() uint { return uint(C.gst_base_src_get_blocks
// GetBufferPool returns the BufferPool used by this source. Unref after usage.
func (g *GstBaseSrc) GetBufferPool() *gst.BufferPool {
return gst.FromGstBufferPoolUnsafe(unsafe.Pointer(C.gst_base_src_get_buffer_pool(g.Instance())))
pool := C.gst_base_src_get_buffer_pool(g.Instance())
if pool == nil {
return nil
}
return gst.FromGstBufferPoolUnsafeFull(unsafe.Pointer(pool))
}
// DoTimestamp will query if the timestamps outgoing on this source's buffers are based on the current

View File

@@ -17,7 +17,7 @@ func goGstBaseSrcGetCaps(src *C.GstBaseSrc, filter *C.GstCaps) *C.GstCaps {
caller := elem.(interface {
GetCaps(*GstBaseSrc, *gst.Caps) *gst.Caps
})
res := caller.GetCaps(wrapGstBaseSrc(src), gst.FromGstCapsUnsafe(unsafe.Pointer(filter)))
res := caller.GetCaps(wrapGstBaseSrc(src), gst.FromGstCapsUnsafeNone(unsafe.Pointer(filter)))
return (*C.GstCaps)(unsafe.Pointer(res.Instance()))
}
@@ -36,7 +36,7 @@ func goGstBaseSrcFixate(src *C.GstBaseSrc, caps *C.GstCaps) *C.GstCaps {
caller := elem.(interface {
Fixate(*GstBaseSrc, *gst.Caps) *gst.Caps
})
res := caller.Fixate(wrapGstBaseSrc(src), gst.FromGstCapsUnsafe(unsafe.Pointer(caps)))
res := caller.Fixate(wrapGstBaseSrc(src), gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps)))
return (*C.GstCaps)(unsafe.Pointer(res.Instance()))
}
@@ -46,7 +46,7 @@ func goGstBaseSrcSetCaps(src *C.GstBaseSrc, filter *C.GstCaps) C.gboolean {
caller := elem.(interface {
SetCaps(*GstBaseSrc, *gst.Caps) bool
})
return gboolean(caller.SetCaps(wrapGstBaseSrc(src), gst.FromGstCapsUnsafe(unsafe.Pointer(filter))))
return gboolean(caller.SetCaps(wrapGstBaseSrc(src), gst.FromGstCapsUnsafeNone(unsafe.Pointer(filter))))
}
//export goGstBaseSrcDecideAllocation
@@ -55,7 +55,7 @@ func goGstBaseSrcDecideAllocation(src *C.GstBaseSrc, query *C.GstQuery) C.gboole
caller := elem.(interface {
DecideAllocation(*GstBaseSrc, *gst.Query) bool
})
return gboolean(caller.DecideAllocation(wrapGstBaseSrc(src), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(caller.DecideAllocation(wrapGstBaseSrc(src), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}
//export goGstBaseSrcStart
@@ -82,7 +82,7 @@ func goGstBaseSrcGetTimes(src *C.GstBaseSrc, buf *C.GstBuffer, start *C.GstClock
caller := elem.(interface {
GetTimes(*GstBaseSrc, *gst.Buffer) (start, end time.Duration)
})
gostart, goend := caller.GetTimes(wrapGstBaseSrc(src), gst.FromGstBufferUnsafe(unsafe.Pointer(buf)))
gostart, goend := caller.GetTimes(wrapGstBaseSrc(src), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf)))
*start = C.GstClockTime(gostart.Nanoseconds())
*end = C.GstClockTime(goend.Nanoseconds())
}
@@ -116,7 +116,7 @@ func goGstBaseSrcPrepareSeekSegment(src *C.GstBaseSrc, seek *C.GstEvent, segment
caller := elem.(interface {
PrepareSeekSegment(*GstBaseSrc, *gst.Event, *gst.Segment) bool
})
return gboolean(caller.PrepareSeekSegment(wrapGstBaseSrc(src), gst.FromGstEventUnsafe(unsafe.Pointer(seek)), gst.FromGstSegmentUnsafe(unsafe.Pointer(segment))))
return gboolean(caller.PrepareSeekSegment(wrapGstBaseSrc(src), gst.FromGstEventUnsafeNone(unsafe.Pointer(seek)), gst.FromGstSegmentUnsafe(unsafe.Pointer(segment))))
}
//export goGstBaseSrcDoSeek
@@ -152,7 +152,7 @@ func goGstBaseSrcQuery(src *C.GstBaseSrc, query *C.GstQuery) C.gboolean {
caller := elem.(interface {
Query(*GstBaseSrc, *gst.Query) bool
})
return gboolean(caller.Query(wrapGstBaseSrc(src), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(caller.Query(wrapGstBaseSrc(src), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}
//export goGstBaseSrcEvent
@@ -161,7 +161,7 @@ func goGstBaseSrcEvent(src *C.GstBaseSrc, event *C.GstEvent) C.gboolean {
caller := elem.(interface {
Event(*GstBaseSrc, *gst.Event) bool
})
return gboolean(caller.Event(wrapGstBaseSrc(src), gst.FromGstEventUnsafe(unsafe.Pointer(event))))
return gboolean(caller.Event(wrapGstBaseSrc(src), gst.FromGstEventUnsafeNone(unsafe.Pointer(event))))
}
//export goGstBaseSrcCreate
@@ -196,5 +196,5 @@ func goGstBaseSrcFill(src *C.GstBaseSrc, offset C.guint64, size C.guint, buf *C.
caller := elem.(interface {
Fill(*GstBaseSrc, uint64, uint, *gst.Buffer) gst.FlowReturn
})
return C.GstFlowReturn(caller.Fill(wrapGstBaseSrc(src), uint64(offset), uint(size), gst.FromGstBufferUnsafe(unsafe.Pointer(buf))))
return C.GstFlowReturn(caller.Fill(wrapGstBaseSrc(src), uint64(offset), uint(size), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf))))
}

View File

@@ -50,7 +50,7 @@ func ToGstBaseTransform(obj interface{}) *GstBaseTransform {
// wrapGstBaseTransform wraps the given unsafe.Pointer in a GstBaseSrc instance.
func wrapGstBaseTransform(obj *C.GstBaseTransform) *GstBaseTransform {
return &GstBaseTransform{gst.FromGstElementUnsafe(unsafe.Pointer(obj))}
return &GstBaseTransform{gst.FromGstElementUnsafeNone(unsafe.Pointer(obj))}
}
// Instance returns the underlying C GstBaseTransform instance
@@ -63,12 +63,19 @@ func (g *GstBaseTransform) GetAllocator() (*gst.Allocator, *gst.AllocationParams
var allocParams C.GstAllocationParams
var allocator *C.GstAllocator
C.gst_base_transform_get_allocator(g.Instance(), &allocator, &allocParams)
return gst.FromGstAllocatorUnsafe(unsafe.Pointer(allocator)), gst.FromGstAllocationParamsUnsafe(unsafe.Pointer(&allocParams))
if allocator == nil {
return nil, nil
}
return gst.FromGstAllocatorUnsafeFull(unsafe.Pointer(allocator)), gst.FromGstAllocationParamsUnsafe(unsafe.Pointer(&allocParams))
}
// GetBufferPool returns the BufferPool used by this transform. Unref after usage.
func (g *GstBaseTransform) GetBufferPool() *gst.BufferPool {
return gst.FromGstBufferPoolUnsafe(unsafe.Pointer(C.gst_base_transform_get_buffer_pool(g.Instance())))
pool := C.gst_base_transform_get_buffer_pool(g.Instance())
if pool == nil {
return nil
}
return gst.FromGstBufferPoolUnsafeFull(unsafe.Pointer(pool))
}
// IsInPlace returns if the transform is configured to do in-place transform.
@@ -88,7 +95,7 @@ func (g *GstBaseTransform) IsQoSEnabled() bool {
// QueuedBuffer returns the currentl queued buffer.
func (g *GstBaseTransform) QueuedBuffer() *gst.Buffer {
return gst.FromGstBufferUnsafe(unsafe.Pointer(g.Instance().queued_buf))
return gst.FromGstBufferUnsafeNone(unsafe.Pointer(g.Instance().queued_buf))
}
// SINCE 1.18
@@ -164,12 +171,12 @@ func (g *GstBaseTransform) SetTransformIPOnPassthrough(enabled bool) {
// SinkPad returns the sink pad object for this element.
func (g *GstBaseTransform) SinkPad() *gst.Pad {
return gst.FromGstPadUnsafe(unsafe.Pointer(g.Instance().sinkpad))
return gst.FromGstPadUnsafeNone(unsafe.Pointer(g.Instance().sinkpad))
}
// SrcPad returns the src pad object for this element.
func (g *GstBaseTransform) SrcPad() *gst.Pad {
return gst.FromGstPadUnsafe(unsafe.Pointer(g.Instance().srcpad))
return gst.FromGstPadUnsafeNone(unsafe.Pointer(g.Instance().srcpad))
}
// UpdateQoS sets the QoS parameters in the transform. This function is called internally when a QOS event is received

View File

@@ -18,7 +18,7 @@ func goGstBaseTransformAcceptCaps(self *C.GstBaseTransform, direction C.GstPadDi
caller := elem.(interface {
AcceptCaps(self *GstBaseTransform, direction gst.PadDirection, caps *gst.Caps) bool
})
return gboolean(caller.AcceptCaps(wrapGstBaseTransform(self), gst.PadDirection(direction), gst.FromGstCapsUnsafe(unsafe.Pointer(caps))))
return gboolean(caller.AcceptCaps(wrapGstBaseTransform(self), gst.PadDirection(direction), gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps))))
}
//export goGstBaseTransformBeforeTransform
@@ -27,7 +27,7 @@ func goGstBaseTransformBeforeTransform(self *C.GstBaseTransform, buffer *C.GstBu
caller := elem.(interface {
BeforeTransform(self *GstBaseTransform, buffer *gst.Buffer)
})
caller.BeforeTransform(wrapGstBaseTransform(self), gst.FromGstBufferUnsafe(unsafe.Pointer(buffer)))
caller.BeforeTransform(wrapGstBaseTransform(self), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buffer)))
}
//export goGstBaseTransformCopyMetadata
@@ -36,7 +36,7 @@ func goGstBaseTransformCopyMetadata(self *C.GstBaseTransform, input, outbuf *C.G
caller := elem.(interface {
CopyMetadata(self *GstBaseTransform, input, output *gst.Buffer) bool
})
return gboolean(caller.CopyMetadata(wrapGstBaseTransform(self), gst.FromGstBufferUnsafe(unsafe.Pointer(input)), gst.FromGstBufferUnsafe(unsafe.Pointer(outbuf))))
return gboolean(caller.CopyMetadata(wrapGstBaseTransform(self), gst.FromGstBufferUnsafeNone(unsafe.Pointer(input)), gst.FromGstBufferUnsafeNone(unsafe.Pointer(outbuf))))
}
//export goGstBaseTransformDecideAllocation
@@ -45,7 +45,7 @@ func goGstBaseTransformDecideAllocation(self *C.GstBaseTransform, query *C.GstQu
caller := elem.(interface {
DecideAllocation(self *GstBaseTransform, query *gst.Query) bool
})
return gboolean(caller.DecideAllocation(wrapGstBaseTransform(self), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(caller.DecideAllocation(wrapGstBaseTransform(self), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}
//export goGstBaseTransformFilterMeta
@@ -56,7 +56,7 @@ func goGstBaseTransformFilterMeta(self *C.GstBaseTransform, query *C.GstQuery, a
})
return gboolean(caller.FilterMeta(
wrapGstBaseTransform(self),
gst.FromGstQueryUnsafe(unsafe.Pointer(query)),
gst.FromGstQueryUnsafeNone(unsafe.Pointer(query)),
glib.Type(api),
gst.FromGstStructureUnsafe(unsafe.Pointer(params)),
))
@@ -69,8 +69,8 @@ func goGstBaseTransformFixateCaps(self *C.GstBaseTransform, direction C.GstPadDi
FixateCaps(self *GstBaseTransform, directon gst.PadDirection, caps *gst.Caps, othercaps *gst.Caps) *gst.Caps
})
wrappedCaps := gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
wrappedOther := gst.FromGstCapsUnsafe(unsafe.Pointer(othercaps))
wrappedCaps := gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps))
wrappedOther := gst.FromGstCapsUnsafeNone(unsafe.Pointer(othercaps))
defer wrappedOther.Unref()
fixated := caller.FixateCaps(wrapGstBaseTransform(self), gst.PadDirection(direction), wrappedCaps, wrappedOther)
@@ -99,7 +99,7 @@ func goGstBaseTransformGetUnitSize(self *C.GstBaseTransform, caps *C.GstCaps, si
caller := elem.(interface {
GetUnitSize(self *GstBaseTransform, caps *gst.Caps) (ok bool, size int64)
})
ok, retsize := caller.GetUnitSize(wrapGstBaseTransform(self), gst.FromGstCapsUnsafe(unsafe.Pointer(caps)))
ok, retsize := caller.GetUnitSize(wrapGstBaseTransform(self), gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps)))
if ok {
*size = C.gsize(retsize)
}
@@ -112,7 +112,7 @@ func goGstBaseTransformPrepareOutputBuffer(self *C.GstBaseTransform, input *C.Gs
caller := elem.(interface {
PrepareOutputBuffer(self *GstBaseTransform, input *gst.Buffer) (gst.FlowReturn, *gst.Buffer)
})
ret, out := caller.PrepareOutputBuffer(wrapGstBaseTransform(self), gst.FromGstBufferUnsafe(unsafe.Pointer(input)))
ret, out := caller.PrepareOutputBuffer(wrapGstBaseTransform(self), gst.FromGstBufferUnsafeNone(unsafe.Pointer(input)))
if out != nil {
C.memcpy(unsafe.Pointer(*outbuf), unsafe.Pointer(out.Instance()), C.sizeof_GstBuffer)
}
@@ -125,7 +125,7 @@ func goGstBaseTransformProposeAllocation(self *C.GstBaseTransform, decide, query
caller := elem.(interface {
ProposeAllocation(self *GstBaseTransform, decideQuery, query *gst.Query) bool
})
return gboolean(caller.ProposeAllocation(wrapGstBaseTransform(self), gst.FromGstQueryUnsafe(unsafe.Pointer(decide)), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(caller.ProposeAllocation(wrapGstBaseTransform(self), gst.FromGstQueryUnsafeNone(unsafe.Pointer(decide)), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}
//export goGstBaseTransformQuery
@@ -134,7 +134,7 @@ func goGstBaseTransformQuery(self *C.GstBaseTransform, direction C.GstPadDirecti
caller := elem.(interface {
Query(self *GstBaseTransform, direction gst.PadDirection, query *gst.Query) bool
})
return gboolean(caller.Query(wrapGstBaseTransform(self), gst.PadDirection(direction), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(caller.Query(wrapGstBaseTransform(self), gst.PadDirection(direction), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}
//export goGstBaseTransformSetCaps
@@ -145,8 +145,8 @@ func goGstBaseTransformSetCaps(self *C.GstBaseTransform, incaps, outcaps *C.GstC
})
return gboolean(caller.SetCaps(
wrapGstBaseTransform(self),
gst.FromGstCapsUnsafe(unsafe.Pointer(incaps)),
gst.FromGstCapsUnsafe(unsafe.Pointer(outcaps)),
gst.FromGstCapsUnsafeNone(unsafe.Pointer(incaps)),
gst.FromGstCapsUnsafeNone(unsafe.Pointer(outcaps)),
))
}
@@ -156,7 +156,7 @@ func goGstBaseTransformSinkEvent(self *C.GstBaseTransform, event *C.GstEvent) C.
caller := elem.(interface {
SinkEvent(self *GstBaseTransform, event *gst.Event) bool
})
return gboolean(caller.SinkEvent(wrapGstBaseTransform(self), gst.FromGstEventUnsafe(unsafe.Pointer(event))))
return gboolean(caller.SinkEvent(wrapGstBaseTransform(self), gst.FromGstEventUnsafeNone(unsafe.Pointer(event))))
}
//export goGstBaseTransformSrcEvent
@@ -165,7 +165,7 @@ func goGstBaseTransformSrcEvent(self *C.GstBaseTransform, event *C.GstEvent) C.g
caller := elem.(interface {
SrcEvent(self *GstBaseTransform, event *gst.Event) bool
})
return gboolean(caller.SrcEvent(wrapGstBaseTransform(self), gst.FromGstEventUnsafe(unsafe.Pointer(event))))
return gboolean(caller.SrcEvent(wrapGstBaseTransform(self), gst.FromGstEventUnsafeNone(unsafe.Pointer(event))))
}
//export goGstBaseTransformStart
@@ -195,7 +195,7 @@ func goGstBaseTransformSubmitInputBuffer(self *C.GstBaseTransform, isDiscont C.g
return C.GstFlowReturn(caller.SubmitInputBuffer(
wrapGstBaseTransform(self),
gobool(isDiscont),
gst.FromGstBufferUnsafe(unsafe.Pointer(input)),
gst.FromGstBufferUnsafeNone(unsafe.Pointer(input)),
))
}
@@ -207,8 +207,8 @@ func goGstBaseTransformTransform(self *C.GstBaseTransform, inbuf, outbuf *C.GstB
})
return C.GstFlowReturn(caller.Transform(
wrapGstBaseTransform(self),
gst.FromGstBufferUnsafe(unsafe.Pointer(inbuf)),
gst.FromGstBufferUnsafe(unsafe.Pointer(outbuf)),
gst.FromGstBufferUnsafeNone(unsafe.Pointer(inbuf)),
gst.FromGstBufferUnsafeNone(unsafe.Pointer(outbuf)),
))
}
@@ -221,8 +221,8 @@ func goGstBaseTransformTransformCaps(self *C.GstBaseTransform, direction C.GstPa
out := caller.TransformCaps(
wrapGstBaseTransform(self),
gst.PadDirection(direction),
gst.FromGstCapsUnsafe(unsafe.Pointer(caps)),
gst.FromGstCapsUnsafe(unsafe.Pointer(filter)),
gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps)),
gst.FromGstCapsUnsafeNone(unsafe.Pointer(filter)),
)
if out == nil {
return nil
@@ -238,7 +238,7 @@ func goGstBaseTransformTransformIP(self *C.GstBaseTransform, buf *C.GstBuffer) C
})
return C.GstFlowReturn(caller.TransformIP(
wrapGstBaseTransform(self),
gst.FromGstBufferUnsafe(unsafe.Pointer(buf)),
gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf)),
))
}
@@ -250,9 +250,9 @@ func goGstBaseTransformTransformMeta(self *C.GstBaseTransform, outbuf *C.GstBuff
})
return gboolean(caller.TransformMeta(
wrapGstBaseTransform(self),
gst.FromGstBufferUnsafe(unsafe.Pointer(outbuf)),
gst.FromGstBufferUnsafeNone(unsafe.Pointer(outbuf)),
gst.FromGstMetaUnsafe(unsafe.Pointer(meta)),
gst.FromGstBufferUnsafe(unsafe.Pointer(inbuf)),
gst.FromGstBufferUnsafeNone(unsafe.Pointer(inbuf)),
))
}
@@ -265,9 +265,9 @@ func goGstBaseTransformTransformSize(self *C.GstBaseTransform, direction C.GstPa
ok, othersize := caller.TransformSize(
wrapGstBaseTransform(self),
gst.PadDirection(direction),
gst.FromGstCapsUnsafe(unsafe.Pointer(caps)),
gst.FromGstCapsUnsafeNone(unsafe.Pointer(caps)),
int64(size),
gst.FromGstCapsUnsafe(unsafe.Pointer(othercaps)),
gst.FromGstCapsUnsafeNone(unsafe.Pointer(othercaps)),
)
if ok {
*outsize = C.gsize(othersize)

View File

@@ -115,14 +115,14 @@ func wrapCollectData(ptr *C.GstCollectData) *CollectData { return &CollectData{p
func (c *CollectData) Instance() *C.GstCollectData { return c.ptr }
// Collect returns the owner CollectPads
func (c *CollectData) Collect() *CollectPads { return wrapCollectPads(c.ptr.collect) }
func (c *CollectData) Collect() *CollectPads { return wrapCollectPadsNone(c.ptr.collect) }
// Pad returns the pad managed by this data.
func (c *CollectData) Pad() *gst.Pad { return gst.FromGstPadUnsafe(unsafe.Pointer(c.ptr.pad)) }
func (c *CollectData) Pad() *gst.Pad { return gst.FromGstPadUnsafeNone(unsafe.Pointer(c.ptr.pad)) }
// Buffer returns the currently queued buffer.
func (c *CollectData) Buffer() *gst.Buffer {
return gst.FromGstBufferUnsafe(unsafe.Pointer(c.ptr.buffer))
return gst.FromGstBufferUnsafeNone(unsafe.Pointer(c.ptr.buffer))
}
// Pos returns the position in the buffer.
@@ -158,12 +158,21 @@ type collectPadsFuncMap struct {
// NewCollectPads creates a new CollectPads instance.
func NewCollectPads() *CollectPads {
return wrapCollectPads(C.gst_collect_pads_new())
return wrapCollectPadsFull(C.gst_collect_pads_new())
}
func wrapCollectPads(ptr *C.GstCollectPads) *CollectPads {
func wrapCollectPadsFull(ptr *C.GstCollectPads) *CollectPads {
collect := &CollectPads{
Object: gst.FromGstObjectUnsafe(unsafe.Pointer(ptr)),
Object: gst.FromGstObjectUnsafeFull(unsafe.Pointer(ptr)),
funcMap: &collectPadsFuncMap{},
}
collect.selfPtr = gopointer.Save(collect)
return collect
}
func wrapCollectPadsNone(ptr *C.GstCollectPads) *CollectPads {
collect := &CollectPads{
Object: gst.FromGstObjectUnsafeNone(unsafe.Pointer(ptr)),
funcMap: &collectPadsFuncMap{},
}
collect.selfPtr = gopointer.Save(collect)
@@ -225,7 +234,7 @@ func (c *CollectPads) ClipRunningTime(data *CollectData, buf *gst.Buffer) (ret g
nil,
))
if goutbuf != nil {
outbuf = gst.FromGstBufferUnsafe(unsafe.Pointer(goutbuf))
outbuf = gst.FromGstBufferUnsafeFull(unsafe.Pointer(goutbuf))
}
return
}
@@ -262,7 +271,7 @@ func (c *CollectPads) Peek(data *CollectData) *gst.Buffer {
if buf == nil {
return nil
}
return gst.FromGstBufferUnsafe(unsafe.Pointer(buf))
return gst.FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
// Pop the buffer currently queued in data. This function should be called with the pads STREAM_LOCK held, such
@@ -272,7 +281,7 @@ func (c *CollectPads) Pop(data *CollectData) *gst.Buffer {
if buf == nil {
return nil
}
return gst.FromGstBufferUnsafe(unsafe.Pointer(buf))
return gst.FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
// QueryDefault is the Default GstCollectPads query handling that elements should always chain up to to ensure
@@ -293,7 +302,7 @@ func (c *CollectPads) ReadBuffer(data *CollectData, size uint) *gst.Buffer {
if buf == nil {
return nil
}
return gst.FromGstBufferUnsafe(unsafe.Pointer(buf))
return gst.FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
// RemovePad removes a pad from the collection of collect pads. This function will also free the GstCollectData
@@ -428,5 +437,5 @@ func (c *CollectPads) TakeBuffer(data *CollectData, size uint) *gst.Buffer {
if buf == nil {
return nil
}
return gst.FromGstBufferUnsafe(unsafe.Pointer(buf))
return gst.FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}

View File

@@ -22,7 +22,7 @@ func goGstCollectPadsBufferFunc(pads *C.GstCollectPads, data *C.GstCollectData,
var wrappedBuf *gst.Buffer
var wrappedData *CollectData
if buf != nil {
wrappedBuf = gst.FromGstBufferUnsafe(unsafe.Pointer(buf))
wrappedBuf = gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf))
defer wrappedBuf.Unref()
}
if data != nil {
@@ -38,7 +38,7 @@ func goGstCollectPadsClipFunc(pads *C.GstCollectPads, data *C.GstCollectData, in
collectPads := iface.(*CollectPads)
f := collectPads.funcMap.clipFunc
buf := gst.FromGstBufferUnsafe(unsafe.Pointer(inbuf))
buf := gst.FromGstBufferUnsafeNone(unsafe.Pointer(inbuf))
defer buf.Unref()
ret, gooutbuf := f(collectPads, wrapCollectData(data), buf)
@@ -64,7 +64,7 @@ func goGstCollectPadsEventFunc(pads *C.GstCollectPads, data *C.GstCollectData, e
collectPads := iface.(*CollectPads)
f := collectPads.funcMap.eventFunc
return gboolean(f(collectPads, wrapCollectData(data), gst.FromGstEventUnsafe(unsafe.Pointer(event))))
return gboolean(f(collectPads, wrapCollectData(data), gst.FromGstEventUnsafeNone(unsafe.Pointer(event))))
}
//export goGstCollectPadsFlushFunc
@@ -91,5 +91,5 @@ func goGstCollectPadsQueryFunc(pads *C.GstCollectPads, data *C.GstCollectData, q
collectPads := iface.(*CollectPads)
f := collectPads.funcMap.queryFunc
return gboolean(f(collectPads, wrapCollectData(data), gst.FromGstQueryUnsafe(unsafe.Pointer(query))))
return gboolean(f(collectPads, wrapCollectData(data), gst.FromGstQueryUnsafeNone(unsafe.Pointer(query))))
}

View File

@@ -28,7 +28,7 @@ func ToGstPushSrc(obj interface{}) *GstPushSrc {
// wrapGstPushSrc wraps the given unsafe.Pointer in a GstPushSrc instance.
func wrapGstPushSrc(obj *C.GstPushSrc) *GstPushSrc {
return &GstPushSrc{&GstBaseSrc{gst.FromGstElementUnsafe(unsafe.Pointer(obj))}}
return &GstPushSrc{&GstBaseSrc{gst.FromGstElementUnsafeNone(unsafe.Pointer(obj))}}
}
// Instance returns the underlying C GstBaseSrc instance

View File

@@ -43,5 +43,5 @@ func goGstPushSrcFill(src *C.GstPushSrc, buf *C.GstBuffer) C.GstFlowReturn {
caller := glib.FromObjectUnsafePrivate(unsafe.Pointer(src)).(interface {
Fill(*GstPushSrc, *gst.Buffer) gst.FlowReturn
})
return C.GstFlowReturn(caller.Fill(wrapGstPushSrc(src), gst.FromGstBufferUnsafe(unsafe.Pointer(buf))))
return C.GstFlowReturn(caller.Fill(wrapGstPushSrc(src), gst.FromGstBufferUnsafeNone(unsafe.Pointer(buf))))
}

View File

@@ -18,7 +18,7 @@ func TypeFindHelper(pad *gst.Pad, size uint64) *gst.Caps {
if caps == nil {
return nil
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// TypeFindHelperForBuffer tries to find what type of data is contained in the given GstBuffer,
@@ -42,7 +42,7 @@ func TypeFindHelperForBuffer(obj *gst.Object, buffer *gst.Buffer) (*gst.Caps, gs
if caps == nil {
return nil, gst.TypeFindProbability(prob)
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
}
// TypeFindHelperForBufferWithExtension ries to find what type of data is contained in the given GstBuffer,
@@ -73,7 +73,7 @@ func TypeFindHelperForBufferWithExtension(obj *gst.Object, buffer *gst.Buffer, e
if caps == nil {
return nil, gst.TypeFindProbability(prob)
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
}
// TypeFindHelperForData tries to find what type of data is contained in the given data,
@@ -97,7 +97,7 @@ func TypeFindHelperForData(obj *gst.Object, data []byte) (*gst.Caps, gst.TypeFin
if caps == nil {
return nil, gst.TypeFindProbability(prob)
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
}
// TypeFindHelperForDataWithExtension ries to find what type of data is contained in the given data,
@@ -128,7 +128,7 @@ func TypeFindHelperForDataWithExtension(obj *gst.Object, data []byte, extension
if caps == nil {
return nil, gst.TypeFindProbability(prob)
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
}
// TypeFindHelperForExtension tries to find the best GstCaps associated with extension.
@@ -148,5 +148,5 @@ func TypeFindHelperForExtension(obj *gst.Object, extension string) *gst.Caps {
if caps == nil {
return nil
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}

View File

@@ -117,7 +117,7 @@ func glistToPadTemplateSlice(glist *C.GList) []*PadTemplate {
out := make([]*PadTemplate, 0)
l.FreeFull(func(item interface{}) {
tmpl := item.(*C.GstPadTemplate)
out = append(out, wrapPadTemplate(toGObject(unsafe.Pointer(tmpl))))
out = append(out, FromGstPadTemplateUnsafeNone(unsafe.Pointer(tmpl)))
})
return out
}

View File

@@ -4,6 +4,7 @@ package gst
import "C"
import (
"runtime"
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
@@ -26,6 +27,7 @@ func NewAllocationParams() *AllocationParams {
ptr: &C.GstAllocationParams{},
}
params.Init()
runtime.SetFinalizer(params, (*AllocationParams).Free)
return params
}
@@ -70,14 +72,19 @@ func (a *AllocationParams) SetPadding(padding int64) { a.ptr.padding = C.gsize(p
// Allocator is a go representation of a GstAllocator
type Allocator struct{ *Object }
// FromGstAllocatorUnsafe wraps the given unsafe.Pointer in an Allocator instance.
func FromGstAllocatorUnsafe(alloc unsafe.Pointer) *Allocator {
return wrapAllocator(toGObject(alloc))
// FromGstAllocatorUnsafeNone wraps the given unsafe.Pointer in an Allocator instance.
func FromGstAllocatorUnsafeNone(alloc unsafe.Pointer) *Allocator {
return wrapAllocator(glib.TransferNone(alloc))
}
// FromGstAllocatorUnsafeFull wraps the given unsafe.Pointer in an Allocator instance.
func FromGstAllocatorUnsafeFull(alloc unsafe.Pointer) *Allocator {
return wrapAllocator(glib.TransferFull(alloc))
}
// DefaultAllocator returns the default GstAllocator.
func DefaultAllocator() *Allocator {
return wrapAllocator(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(C.gst_allocator_find(nil)))})
return wrapAllocator(glib.TransferFull(unsafe.Pointer(C.gst_allocator_find(nil))))
}
// Instance returns the underlying GstAllocator instance.
@@ -96,7 +103,8 @@ func (a *Allocator) MemType() string { return C.GoString(a.Instance().mem_type)
// The alignment in params is given as a bitmask so that align + 1 equals the amount of bytes to
// align to. For example, to align to 8 bytes, use an alignment of 7.
func (a *Allocator) Alloc(size int64, params *AllocationParams) *Memory {
return wrapMemory(C.gst_allocator_alloc(a.Instance(), C.gsize(size), params.ptr))
mem := C.gst_allocator_alloc(a.Instance(), C.gsize(size), params.ptr)
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
}
// Free memory that was originally allocated with this allocator.

View File

@@ -86,7 +86,7 @@ func NewBin(name string) *Bin {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
bin := C.gst_bin_new((*C.gchar)(unsafe.Pointer(cName)))
return wrapBin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(bin))})
return wrapBin(glib.TransferNone(unsafe.Pointer(bin)))
}
// ToGstBin wraps the given glib.Object, gst.Object, or gst.Element in a Bin instance. Only
@@ -114,7 +114,7 @@ func (b *Bin) GetElementByName(name string) (*Element, error) {
if elem == nil {
return nil, fmt.Errorf("Could not find element with name %s", name)
}
return wrapElement(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(elem))}), nil
return wrapElement(glib.TransferFull(unsafe.Pointer(elem))), nil
}
// GetElementByNameRecursive returns the element with the given name. If it is not
@@ -126,7 +126,7 @@ func (b *Bin) GetElementByNameRecursive(name string) (*Element, error) {
if elem == nil {
return nil, fmt.Errorf("Could not find element with name %s", name)
}
return wrapElement(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(elem))}), nil
return wrapElement(glib.TransferFull(unsafe.Pointer(elem))), nil
}
// GetElements returns a list of the elements added to this pipeline.
@@ -171,7 +171,7 @@ func (b *Bin) GetByInterface(iface glib.Interface) (*Element, error) {
if elem == nil {
return nil, fmt.Errorf("Could not find any elements implementing %s", iface.Type().Name())
}
return wrapElement(toGObject(unsafe.Pointer(elem))), nil
return wrapElement(glib.TransferFull(unsafe.Pointer(elem))), nil
}
// GetAllByInterface looks for all elements inside the bin that implements the given interface. You can
@@ -235,7 +235,7 @@ func (b *Bin) FindUnlinkedPad(direction PadDirection) *Pad {
if pad == nil {
return nil
}
return wrapPad(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(pad))})
return wrapPad(glib.TransferFull(unsafe.Pointer(pad)))
}
// GetSuppressedFlags returns the suppressed flags of the bin.
@@ -321,7 +321,7 @@ func iteratorToElementSlice(iterator *C.GstIterator) ([]*Element, error) {
case C.GST_ITERATOR_OK:
cElemVoid := C.g_value_get_object((*C.GValue)(gval))
cElem := (*C.GstElement)(cElemVoid)
elems = append(elems, wrapElement(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(cElem))}))
elems = append(elems, wrapElement(glib.TransferFull(unsafe.Pointer(cElem))))
C.g_value_reset((*C.GValue)(gval))
default:
return nil, errors.New("Element iterator failed")

View File

@@ -23,6 +23,7 @@ import (
"bytes"
"io"
"io/ioutil"
"runtime"
"time"
"unsafe"
@@ -39,15 +40,30 @@ type Buffer struct {
mapInfo *MapInfo
}
// FromGstBufferUnsafe wraps the given C GstBuffer in the go type. It is meant for internal usage
// and exported for visibility to other packages.
func FromGstBufferUnsafe(buf unsafe.Pointer) *Buffer {
return wrapBuffer((*C.GstBuffer)(buf))
// // FromGstBufferUnsafe wraps the given C GstBuffer in the go type. It is meant for internal usage
// // and exported for visibility to other packages.
// func FromGstBufferUnsafe(buf unsafe.Pointer) *Buffer {
// return FromGstBufferUnsafeNone(buf)
// }
// FromGstBufferUnsafeNone is an alias to FromGstBufferUnsafe.
func FromGstBufferUnsafeNone(buf unsafe.Pointer) *Buffer {
wrapped := wrapBuffer((*C.GstBuffer)(buf))
wrapped.Ref()
runtime.SetFinalizer(wrapped, (*Buffer).Unref)
return wrapped
}
// FromGstBufferUnsafeFull wraps the given buffer without taking an additional reference.
func FromGstBufferUnsafeFull(buf unsafe.Pointer) *Buffer {
wrapped := wrapBuffer((*C.GstBuffer)(buf))
runtime.SetFinalizer(wrapped, (*Buffer).Unref)
return wrapped
}
// NewEmptyBuffer returns a new empty buffer.
func NewEmptyBuffer() *Buffer {
return wrapBuffer(C.gst_buffer_new())
return FromGstBufferUnsafeFull(unsafe.Pointer(C.gst_buffer_new()))
}
// NewBufferWithSize is a convenience wrapped for NewBufferrAllocate with the default allocator
@@ -76,14 +92,14 @@ func NewBufferAllocate(alloc *Allocator, params *AllocationParams, size int64) *
if buf == nil {
return nil
}
return wrapBuffer(buf)
return FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
// NewBufferFromBytes returns a new buffer from the given byte slice.
func NewBufferFromBytes(b []byte) *Buffer {
gbytes := C.g_bytes_new((C.gconstpointer)(unsafe.Pointer(&b[0])), C.gsize(len(b)))
defer C.g_bytes_unref(gbytes) // gstreamer takes another ref so we don't need ours after returning
return wrapBuffer(C.gst_buffer_new_wrapped_bytes(gbytes))
defer C.g_bytes_unref(gbytes)
return FromGstBufferUnsafeFull(unsafe.Pointer(C.gst_buffer_new_wrapped_bytes(gbytes)))
}
// NewBufferFromReader returns a new buffer from the given io.Reader.
@@ -131,7 +147,7 @@ func NewBufferFull(flags MemoryFlags, data []byte, maxSize, offset, size int64,
if buf == nil {
return nil
}
return wrapBuffer(buf)
return FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
// Instance returns the underlying GstBuffer instance.
@@ -300,7 +316,7 @@ func (b *Buffer) AddReferenceTimestampMeta(ref *Caps, timestamp, duration time.D
// Append will append all the memory from the given buffer to this one. The result buffer will
// contain a concatenation of the memory of the two buffers.
func (b *Buffer) Append(buf *Buffer) *Buffer {
return wrapBuffer(C.gst_buffer_append(b.Instance(), buf.Instance()))
return FromGstBufferUnsafeFull(unsafe.Pointer(C.gst_buffer_append(b.Ref().Instance(), buf.Ref().Instance())))
}
// AppendMemory append the memory block to this buffer. This function takes ownership of
@@ -308,25 +324,31 @@ func (b *Buffer) Append(buf *Buffer) *Buffer {
//
// This function is identical to InsertMemory with an index of -1.
func (b *Buffer) AppendMemory(mem *Memory) {
C.gst_buffer_append_memory(b.Instance(), mem.Instance())
C.gst_buffer_append_memory(b.Instance(), mem.Ref().Instance())
}
// AppendRegion will append size bytes at offset from the given buffer to this one. The result
// buffer will contain a concatenation of the memory of this buffer and the requested region of
// the one provided.
func (b *Buffer) AppendRegion(buf *Buffer, offset, size int64) *Buffer {
newbuf := C.gst_buffer_append_region(b.Instance(), buf.Instance(), C.gssize(offset), C.gssize(size))
return wrapBuffer(newbuf)
newbuf := C.gst_buffer_append_region(b.Ref().Instance(), buf.Ref().Instance(), C.gssize(offset), C.gssize(size))
return FromGstBufferUnsafeFull(unsafe.Pointer(newbuf))
}
// Copy creates a copy of this buffer. This will only copy the buffer's data to a newly allocated
// Memory if needed (if the type of memory requires it), otherwise the underlying data is just referenced.
// Check DeepCopy if you want to force the data to be copied to newly allocated Memory.
func (b *Buffer) Copy() *Buffer { return wrapBuffer(C.gst_buffer_copy(b.Instance())) }
func (b *Buffer) Copy() *Buffer {
buf := C.gst_buffer_copy(b.Instance())
return FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
// DeepCopy creates a copy of the given buffer. This will make a newly allocated copy of the data
// the source buffer contains.
func (b *Buffer) DeepCopy() *Buffer { return wrapBuffer(C.gst_buffer_copy_deep(b.Instance())) }
func (b *Buffer) DeepCopy() *Buffer {
buf := C.gst_buffer_copy_deep(b.Instance())
return FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
// CopyInto copies the information from this buffer into the given one. If the given buffer already
// contains memory and flags contains BufferCopyMemory, the memory from this one will be appended to
@@ -416,7 +438,11 @@ func (b *Buffer) ForEachMeta(f func(meta *Meta) bool) bool {
// GetAllMemory retrieves all the memory inside this buffer.
func (b *Buffer) GetAllMemory() *Memory {
return wrapMemory(C.gst_buffer_get_all_memory(b.Instance()))
mem := C.gst_buffer_get_all_memory(b.Instance())
if mem == nil {
return nil
}
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
}
// GetFlags returns the flags on this buffer.
@@ -430,7 +456,7 @@ func (b *Buffer) GetMemory(idx uint) *Memory {
if mem == nil {
return nil
}
return wrapMemory(mem)
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
}
// GetMemoryRange retrieves length memory blocks in buffer starting at idx. The memory blocks
@@ -440,7 +466,7 @@ func (b *Buffer) GetMemoryRange(idx uint, length int) *Memory {
if mem == nil {
return nil
}
return wrapMemory(mem)
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
}
// GetMeta retrieves the metadata for the given api on buffer. When there is no such metadata,
@@ -465,16 +491,24 @@ func (b *Buffer) GetNumMetas(api glib.Type) uint {
//
// Buffers can contain multiple ReferenceTimestampMeta metadata items.
func (b *Buffer) GetReferenceTimestampMeta(caps *Caps) *ReferenceTimestampMeta {
meta := C.gst_buffer_get_reference_timestamp_meta(b.Instance(), caps.Instance())
var meta *C.GstReferenceTimestampMeta
if caps == nil {
meta = C.gst_buffer_get_reference_timestamp_meta(b.Instance(), nil)
} else {
meta = C.gst_buffer_get_reference_timestamp_meta(b.Instance(), caps.Instance())
}
if meta == nil {
return nil
}
return &ReferenceTimestampMeta{
refMeta := &ReferenceTimestampMeta{
Parent: wrapMeta(&meta.parent),
Reference: wrapCaps(meta.reference),
Timestamp: time.Duration(meta.timestamp),
Duration: time.Duration(meta.duration),
}
if meta.reference != nil {
refMeta.Reference = wrapCaps(meta.reference)
}
return refMeta
}
// GetSize retrieves the number of Memory blocks in the bffer.
@@ -513,7 +547,7 @@ func (b *Buffer) HasFlags(flags BufferFlags) bool {
// Only the value from GetMaxBufferMemory can be added to a buffer. If more memory is added, existing memory
// blocks will automatically be merged to make room for the new memory.
func (b *Buffer) InsertMemory(mem *Memory, idx int) {
C.gst_buffer_insert_memory(b.Instance(), C.gint(idx), mem.Instance())
C.gst_buffer_insert_memory(b.Instance(), C.gint(idx), mem.Ref().Instance())
}
// IsAllMemoryWritable checks if all memory blocks in buffer are writable.
@@ -579,16 +613,13 @@ func (b *Buffer) Map(flags MapFlags) *MapInfo {
if b.mapInfo != nil {
return b.mapInfo
}
mapInfo := C.malloc(C.sizeof_GstMapInfo)
var mapInfo C.GstMapInfo
C.gst_buffer_map(
(*C.GstBuffer)(b.Instance()),
(*C.GstMapInfo)(mapInfo),
(*C.GstMapInfo)(&mapInfo),
C.GstMapFlags(flags),
)
if mapInfo == C.NULL {
return nil
}
b.mapInfo = wrapMapInfo((*C.GstMapInfo)(mapInfo))
b.mapInfo = wrapMapInfo((*C.GstMapInfo)(&mapInfo))
return b.mapInfo
}
@@ -598,7 +629,7 @@ func (b *Buffer) Unmap() {
return
}
C.gst_buffer_unmap(b.Instance(), (*C.GstMapInfo)(b.mapInfo.Instance()))
C.free(unsafe.Pointer(b.mapInfo.Instance()))
b.mapInfo = nil
}
// MapRange maps the info of length merged memory blocks starting at idx in buffer.
@@ -611,17 +642,17 @@ func (b *Buffer) Unmap() {
//
// Unmap the Buffer after usage.
func (b *Buffer) MapRange(idx uint, length int, flags MapFlags) *MapInfo {
mapInfo := C.malloc(C.sizeof_GstMapInfo)
if b.mapInfo != nil {
return b.mapInfo
}
var mapInfo C.GstMapInfo
C.gst_buffer_map_range(
(*C.GstBuffer)(b.Instance()),
C.guint(idx), C.gint(length),
(*C.GstMapInfo)(mapInfo),
(*C.GstMapInfo)(&mapInfo),
C.GstMapFlags(flags),
)
if mapInfo == C.NULL {
return nil
}
b.mapInfo = wrapMapInfo((*C.GstMapInfo)(mapInfo))
b.mapInfo = wrapMapInfo((*C.GstMapInfo)(&mapInfo))
return b.mapInfo
}
@@ -641,7 +672,7 @@ func (b *Buffer) PeekMemory(idx uint) *Memory {
if mem == nil {
return nil
}
return wrapMemory(mem)
return FromGstMemoryUnsafeNone(unsafe.Pointer(mem))
}
// PrependMemory prepends the memory block mem to this buffer. This function takes ownership of
@@ -649,7 +680,7 @@ func (b *Buffer) PeekMemory(idx uint) *Memory {
//
// This function is identical to InsertMemory with an index of 0.
func (b *Buffer) PrependMemory(mem *Memory) {
C.gst_buffer_prepend_memory(b.Instance(), mem.Instance())
C.gst_buffer_prepend_memory(b.Instance(), mem.Ref().Instance())
}
// RemoveAllMemory removes all memory blocks in the buffer.
@@ -672,12 +703,12 @@ func (b *Buffer) RemoveMeta(meta *Meta) bool {
// ReplaceAllMemory replaces all the memory in this buffer with that provided.
func (b *Buffer) ReplaceAllMemory(mem *Memory) {
C.gst_buffer_replace_all_memory(b.Instance(), mem.Instance())
C.gst_buffer_replace_all_memory(b.Instance(), mem.Ref().Instance())
}
// ReplaceMemory replaces the memory at the given index with the given memory.
func (b *Buffer) ReplaceMemory(mem *Memory, idx uint) {
C.gst_buffer_replace_memory(b.Instance(), C.guint(idx), mem.Instance())
C.gst_buffer_replace_memory(b.Instance(), C.guint(idx), mem.Ref().Instance())
}
// ReplaceMemoryRange replaces length memory blocks in the buffer starting at idx with
@@ -687,7 +718,7 @@ func (b *Buffer) ReplaceMemory(mem *Memory, idx uint) {
//
// The buffer should be writable.
func (b *Buffer) ReplaceMemoryRange(idx uint, length int, mem *Memory) {
C.gst_buffer_replace_memory_range(b.Instance(), C.guint(idx), C.gint(length), mem.Instance())
C.gst_buffer_replace_memory_range(b.Instance(), C.guint(idx), C.gint(length), mem.Ref().Instance())
}
// Resize sets the offset and total size of the memory blocks in this buffer.

View File

@@ -12,6 +12,7 @@ gboolean cgoBufferListForEachCb (GstBuffer ** buffer, guint idx, gpointer user_d
*/
import "C"
import (
"runtime"
"unsafe"
gopointer "github.com/mattn/go-pointer"
@@ -25,7 +26,7 @@ type BufferList struct {
// NewBufferList returns a new BufferList. The given slice can be nil and the returned
// buffer list will be empty.
func NewBufferList(buffers []*Buffer) *BufferList {
bufList := wrapBufferList(C.gst_buffer_list_new())
bufList := FromGstBufferListUnsafeFull(unsafe.Pointer(C.gst_buffer_list_new()))
if buffers == nil {
return bufList
}
@@ -37,13 +38,28 @@ func NewBufferList(buffers []*Buffer) *BufferList {
// NewBufferListSized creates a new BufferList with the given size.
func NewBufferListSized(size uint) *BufferList {
return wrapBufferList(C.gst_buffer_list_new_sized(C.guint(size)))
return FromGstBufferListUnsafeFull(unsafe.Pointer(C.gst_buffer_list_new_sized(C.guint(size))))
}
// FromGstBufferListUnsafe wraps the given unsafe.Pointer in a BufferList instance. It is meant for internal usage
// and exported for visibility to other packages.
func FromGstBufferListUnsafe(ptr unsafe.Pointer) *BufferList {
return wrapBufferList((*C.GstBufferList)(ptr))
// // FromGstBufferListUnsafe wraps the given C GstBufferList in the go type. It is meant for internal usage
// // and exported for visibility to other packages.
// func FromGstBufferListUnsafe(buf unsafe.Pointer) *BufferList {
// return FromGstBufferListUnsafeNone(buf)
// }
// FromGstBufferListUnsafeNone is an alias to FromGstBufferListUnsafe.
func FromGstBufferListUnsafeNone(buf unsafe.Pointer) *BufferList {
wrapped := wrapBufferList((*C.GstBufferList)(buf))
wrapped.Ref()
runtime.SetFinalizer(wrapped, (*BufferList).Unref)
return wrapped
}
// FromGstBufferListUnsafeFull wraps the given buffer without taking an additional reference.
func FromGstBufferListUnsafeFull(buf unsafe.Pointer) *BufferList {
wrapped := wrapBufferList((*C.GstBufferList)(buf))
runtime.SetFinalizer(wrapped, (*BufferList).Unref)
return wrapped
}
// Instance returns the underlying GstBufferList.
@@ -57,13 +73,13 @@ func (b *BufferList) CalculateSize() int64 {
// Copy creates a shallow copy of the given buffer list. This will make a newly allocated copy of the
// source list with copies of buffer pointers. The refcount of buffers pointed to will be increased by one.
func (b *BufferList) Copy() *BufferList {
return wrapBufferList(C.gst_buffer_list_copy(b.Instance()))
return FromGstBufferListUnsafeFull(unsafe.Pointer(C.gst_buffer_list_copy(b.Instance())))
}
// DeepCopy creates a copy of the given buffer list. This will make a newly allocated copy of each buffer
// that the source buffer list contains.
func (b *BufferList) DeepCopy() *BufferList {
return wrapBufferList(C.gst_buffer_list_copy_deep(b.Instance()))
return FromGstBufferListUnsafeFull(unsafe.Pointer(C.gst_buffer_list_copy_deep(b.Instance())))
}
// IsWritable returns true if this BufferList is writable.
@@ -74,7 +90,7 @@ func (b *BufferList) IsWritable() bool {
// MakeWritable makes a writable buffer list from this one. If the source buffer list is already writable,
// this will simply return the same buffer list. A copy will otherwise be made using Copy.
func (b *BufferList) MakeWritable() *BufferList {
return wrapBufferList(C.makeBufferListWritable(b.Instance()))
return FromGstBufferListUnsafeFull(unsafe.Pointer(C.makeBufferListWritable(b.Instance())))
}
// ForEach calls the given function for each buffer in list.
@@ -95,21 +111,21 @@ func (b *BufferList) ForEach(f func(buf *Buffer, idx uint) bool) {
//
// You must make sure that idx does not exceed the number of buffers available.
func (b *BufferList) GetBufferAt(idx uint) *Buffer {
return wrapBuffer(C.gst_buffer_list_get(b.Instance(), C.guint(idx)))
return FromGstBufferUnsafeNone(unsafe.Pointer(C.gst_buffer_list_get(b.Instance(), C.guint(idx))))
}
// GetWritableBufferAt gets the buffer at idx, ensuring it is a writable buffer.
//
// You must make sure that idx does not exceed the number of buffers available.
func (b *BufferList) GetWritableBufferAt(idx uint) *Buffer {
return wrapBuffer(C.gst_buffer_list_get_writable(b.Instance(), C.guint(idx)))
return FromGstBufferUnsafeNone(unsafe.Pointer(C.gst_buffer_list_get_writable(b.Instance(), C.guint(idx))))
}
// Insert inserts a buffer at idx in the list. Other buffers are moved to make room for this new buffer.
//
// A -1 value for idx will append the buffer at the end.
func (b *BufferList) Insert(idx int, buf *Buffer) {
C.gst_buffer_list_insert(b.Instance(), C.gint(idx), buf.Instance())
C.gst_buffer_list_insert(b.Instance(), C.gint(idx), buf.Ref().Instance())
}
// Length returns the number of buffers in the list.

View File

@@ -19,12 +19,26 @@ type BufferPool struct{ *Object }
// NewBufferPool returns a new BufferPool instance.
func NewBufferPool() *BufferPool {
pool := C.gst_buffer_pool_new()
return wrapBufferPool(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(pool))})
return FromGstBufferPoolUnsafeFull(unsafe.Pointer(pool))
}
// FromGstBufferPoolUnsafe wraps the given unsafe.Pointer in a BufferPool instance.
func FromGstBufferPoolUnsafe(bufferPool unsafe.Pointer) *BufferPool {
return wrapBufferPool(toGObject(bufferPool))
// FromGstBufferPoolUnsafeNone wraps the given unsafe.Pointer in a BufferPool instance. It takes a
// ref and places a runtime finalizer on the resulting object.
func FromGstBufferPoolUnsafeNone(bufferPool unsafe.Pointer) *BufferPool {
pool := wrapBufferPool(glib.TransferNone(bufferPool))
return pool
}
// // FromGstBufferPoolUnsafe is an alias to FromGstBufferPoolUnsafeNone.
// func FromGstBufferPoolUnsafe(bufferPool unsafe.Pointer) *BufferPool {
// return FromGstBufferPoolUnsafeNone(bufferPool)
// }
// FromGstBufferPoolUnsafeFull wraps the given unsafe.Pointer in a BufferPool instance. It just
// places a runtime finalizer on the resulting object.
func FromGstBufferPoolUnsafeFull(bufferPool unsafe.Pointer) *BufferPool {
pool := wrapBufferPool(glib.TransferFull(bufferPool))
return pool
}
// Instance returns the underlying GstBufferPool instance.
@@ -52,18 +66,26 @@ func (b *BufferPool) AcquireBuffer(params *BufferPoolAcquireParams) (*Buffer, Fl
gparams.stop = C.gint64(params.Stop)
gparams.flags = C.GstBufferPoolAcquireFlags(params.Flags)
ret := C.gst_buffer_pool_acquire_buffer(b.Instance(), &buf, gparams)
return wrapBuffer(buf), FlowReturn(ret)
if FlowReturn(ret) != FlowOK {
return nil, FlowReturn(ret)
}
return FromGstBufferUnsafeFull(unsafe.Pointer(buf)), FlowReturn(ret)
}
ret := C.gst_buffer_pool_acquire_buffer(b.Instance(), &buf, nil)
return wrapBuffer(buf), FlowReturn(ret)
if FlowReturn(ret) != FlowOK {
return nil, FlowReturn(ret)
}
return FromGstBufferUnsafeFull(unsafe.Pointer(buf)), FlowReturn(ret)
}
// GetConfig retrieves a copy of the current configuration of the pool. This configuration can either
// be modified and used for the SetConfig call or it must be freed after usage.
// be modified and used for the SetConfig call or it must be freed after usage with Free.
func (b *BufferPool) GetConfig() *BufferPoolConfig {
st := wrapStructure(C.gst_buffer_pool_get_config(b.Instance()))
cfg := BufferPoolConfig(*st)
return &cfg
st := C.gst_buffer_pool_get_config(b.Instance())
if st == nil {
return nil
}
return &BufferPoolConfig{Structure: FromGstStructureUnsafe(unsafe.Pointer(st))}
}
// GetOptions retrieves a list of supported bufferpool options for the pool. An option would typically
@@ -89,7 +111,7 @@ func (b *BufferPool) IsActive() bool { return gobool(C.gst_buffer_pool_is_active
//
// This function is usually called automatically when the last ref on buffer disappears.
func (b *BufferPool) ReleaseBuffer(buf *Buffer) {
C.gst_buffer_pool_release_buffer(b.Instance(), buf.Instance())
C.gst_buffer_pool_release_buffer(b.Instance(), buf.Ref().Instance())
}
// SetActive can be used to control the active state of pool. When the pool is inactive, new calls to
@@ -126,10 +148,7 @@ func (b *BufferPool) SetFlushing(flushing bool) {
// BufferPoolConfig wraps the Structure interface with extra methods for interacting with BufferPool
// configurations.
type BufferPoolConfig Structure
// Instance returns the structure backing this config.
func (b *BufferPoolConfig) Instance() *C.GstStructure { return C.toGstStructure(b.ptr) }
type BufferPoolConfig struct{ *Structure }
// AddOption enables the option in config. This will instruct the bufferpool to enable the specified option
// on the buffers that it allocates.
@@ -146,7 +165,11 @@ func (b *BufferPoolConfig) GetAllocator() (*Allocator, *AllocationParams) {
var allocator *C.GstAllocator
var params C.GstAllocationParams
C.gst_buffer_pool_config_get_allocator(b.Instance(), &allocator, &params)
return wrapAllocator(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(allocator))}), &AllocationParams{ptr: &params}
var allo *Allocator
if allocator != nil {
allo = wrapAllocator(glib.TransferNone(unsafe.Pointer(allocator)))
}
return allo, &AllocationParams{ptr: &params}
}
// GetOption retrieves the option at index of the options API array.
@@ -193,7 +216,17 @@ func (b *BufferPoolConfig) NumOptions() uint {
// Some pools are, for example, not able to operate with different allocators or cannot allocate with the values
// specified in params. Use GetConfig on the pool to get the currently used values.
func (b *BufferPoolConfig) SetAllocator(allocator *Allocator, params *AllocationParams) {
if allocator == nil && params != nil {
C.gst_buffer_pool_config_set_allocator(b.Instance(), nil, params.Instance())
return
}
if allocator != nil && params == nil {
C.gst_buffer_pool_config_set_allocator(b.Instance(), allocator.Instance(), nil)
return
}
if allocator != nil && params != nil {
C.gst_buffer_pool_config_set_allocator(b.Instance(), allocator.Instance(), params.Instance())
}
}
// SetParams configures the config with the given parameters.

View File

@@ -20,10 +20,7 @@ GstBusSyncReply cgoBusSyncHandler (GstBus * bus, GstMessage * message, gpointer
import "C"
import (
"errors"
"reflect"
"runtime/debug"
"sync"
"time"
"unsafe"
@@ -35,9 +32,6 @@ import (
// popping messages from the queue.
type Bus struct {
*Object
msgChannels []chan *Message
mux sync.Mutex
}
// NewBus returns a new Bus instance.
@@ -75,10 +69,17 @@ type Bus struct {
// // > [fakesrc0] ASYNC-START - Async task started
//
func NewBus() *Bus {
bus := C.gst_bus_new()
return wrapBus(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(bus))})
return FromGstBusUnsafeFull(unsafe.Pointer(C.gst_bus_new()))
}
// FromGstBusUnsafeNone wraps the given unsafe.Pointer in a bus. It takes a ref on the bus and sets
// a runtime finalizer on it.
func FromGstBusUnsafeNone(bus unsafe.Pointer) *Bus { return wrapBus(glib.TransferNone(bus)) }
// FromGstBusUnsafeFull wraps the given unsafe.Pointer in a bus. It does not increase the ref count
// and places a runtime finalizer on the instance.
func FromGstBusUnsafeFull(bus unsafe.Pointer) *Bus { return wrapBus(glib.TransferFull(bus)) }
// Instance returns the underlying GstBus instance.
func (b *Bus) Instance() *C.GstBus { return C.toGstBus(b.Unsafe()) }
@@ -92,41 +93,6 @@ func (b *Bus) Instance() *C.GstBus { return C.toGstBus(b.Unsafe()) }
// as many times as this function is called.
func (b *Bus) AddSignalWatch() { C.gst_bus_add_signal_watch(b.Instance()) }
func (b *Bus) deliverMessages() {
for {
msg := b.BlockPopMessage()
if msg == nil {
return
}
b.mux.Lock()
for _, ch := range b.msgChannels {
ch <- msg.Ref()
}
b.mux.Unlock()
msg.Unref()
}
}
// MessageChan returns a new channel to listen for messages asynchronously. Messages
// should be unreffed after each usage. Messages are delivered to channels in the
// order in which this function was called.
//
// While a message is being delivered to created channels, there is a lock on creating
// new ones.
//
// It is much safer and easier to use the AddWatch method or other polling functions. Only use this method if you
// are unable to also run a MainLoop, or for convenience sake.
func (b *Bus) MessageChan() chan *Message {
b.mux.Lock()
defer b.mux.Unlock()
ch := make(chan *Message)
b.msgChannels = append(b.msgChannels, ch)
if len(b.msgChannels) == 1 {
go b.deliverMessages()
}
return ch
}
// PopMessage attempts to pop a message from the bus. It returns nil if none are available.
// The message should be unreffed after usage.
//
@@ -185,9 +151,9 @@ func (b *Bus) AddWatch(busFunc BusWatchFunc) bool {
// CreateWatch creates a watch and returns the GSource to be added to a main loop.
// TODO: the return values from this function should be type casted and the MainLoop
// should offer methods for using the return of this function.
func (b *Bus) CreateWatch() *C.GSource {
return C.gst_bus_create_watch(b.Instance())
}
// func (b *Bus) CreateWatch() *C.GSource {
// return C.gst_bus_create_watch(b.Instance())
// }
// RemoveWatch will remove any watches installed on the bus. This can also be accomplished
// by returning false from a previously installed function.
@@ -255,7 +221,11 @@ func (b *Bus) HavePending() bool {
// Peek peeks the message on the top of the bus' queue. The message will remain on the bus'
// message queue. A reference is returned, and needs to be unreffed by the caller.
func (b *Bus) Peek() *Message {
return wrapMessage(C.gst_bus_peek(b.Instance()))
msg := C.gst_bus_peek(b.Instance())
if msg == nil {
return nil
}
return FromGstMessageUnsafeFull(unsafe.Pointer(msg))
}
// Poll the bus for messages. Will block while waiting for messages to come. You can specify a maximum
@@ -288,7 +258,7 @@ func (b *Bus) Poll(msgTypes MessageType, timeout time.Duration) *Message {
if msg == nil {
return nil
}
return wrapMessage(msg)
return FromGstMessageUnsafeFull(unsafe.Pointer(msg))
}
// Pop pops a message from the bus, or returns nil if none are available.
@@ -297,7 +267,7 @@ func (b *Bus) Pop() *Message {
if msg == nil {
return nil
}
return wrapMessage(msg)
return FromGstMessageUnsafeFull(unsafe.Pointer(msg))
}
// PopFiltered gets a message matching type from the bus. Will discard all messages on the bus that do not match type
@@ -309,28 +279,12 @@ func (b *Bus) PopFiltered(msgTypes MessageType) *Message {
if msg == nil {
return nil
}
return wrapMessage(msg)
return FromGstMessageUnsafeFull(unsafe.Pointer(msg))
}
// Post a new message on the bus. The bus takes ownership of the message.
func (b *Bus) Post(msg *Message) bool {
return gobool(C.gst_bus_post(b.Instance(), msg.Instance()))
}
// PostError is a wrapper for creating a new error mesesage and then posting it to the bus.
// It gathers stack info from the caller and appends it to the debug info in the error. And optional
// error object can be provided and will be added to the structure of the error.
func (b *Bus) PostError(src interface{}, msg string, err error) bool {
gerr := NewGError(1, errors.New(msg))
var st *Structure
if err != nil {
st = NewStructure("go-error")
if addErr := st.SetValue("error", err.Error()); addErr != nil {
b.Log(CAT, LevelWarning, "failed to set error message to structure")
}
}
gstMsg := NewErrorMessage(src, gerr, string(debug.Stack()), st)
return b.Post(gstMsg)
return gobool(C.gst_bus_post(b.Instance(), msg.Ref().Instance()))
}
// SetFlushing sets whether to flush out and unref any messages queued in the bus. Releases references to the message origin
@@ -372,7 +326,7 @@ func (b *Bus) TimedPop(dur time.Duration) *Message {
if msg == nil {
return nil
}
return wrapMessage(msg)
return FromGstMessageUnsafeFull(unsafe.Pointer(msg))
}
// TimedPopFiltered gets a message from the bus whose type matches the message type mask types, waiting up to the specified timeout
@@ -391,5 +345,5 @@ func (b *Bus) TimedPopFiltered(dur time.Duration, msgTypes MessageType) *Message
if msg == nil {
return nil
}
return wrapMessage(msg)
return FromGstMessageUnsafeFull(unsafe.Pointer(msg))
}

View File

@@ -14,7 +14,7 @@ gboolean cgoCapsMapFunc (GstCapsFeatures * features, GstStructure * structure, g
import "C"
import (
"fmt"
"runtime"
"unsafe"
gopointer "github.com/mattn/go-pointer"
@@ -29,9 +29,35 @@ type Caps struct {
native *C.GstCaps
}
// FromGstCapsUnsafe wraps the pointer to the given C GstCaps with the go type.
// FromGstCapsUnsafeNone wraps the pointer to the given C GstCaps with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstCapsUnsafe(caps unsafe.Pointer) *Caps { return wrapCaps(C.toGstCaps(caps)) }
// A ref is taken on the caps and finalizer placed on the object.
func FromGstCapsUnsafeNone(caps unsafe.Pointer) *Caps {
if caps == nil {
return nil
}
gocaps := wrapCaps(C.toGstCaps(caps))
gocaps.Ref()
runtime.SetFinalizer(gocaps, (*Caps).Unref)
return gocaps
}
// // FromGstCapsUnsafe is an alias to FromGstCapsUnsafeNone.
// func FromGstCapsUnsafe(caps unsafe.Pointer) *Caps {
// return FromGstCapsUnsafeNone(caps)
// }
// FromGstCapsUnsafeFull wraps the pointer to the given C GstCaps with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
// A finalizer is placed on the object to Unref after leaving scope.
func FromGstCapsUnsafeFull(caps unsafe.Pointer) *Caps {
if caps == nil {
return nil
}
gocaps := wrapCaps(C.toGstCaps(caps))
runtime.SetFinalizer(gocaps, (*Caps).Unref)
return gocaps
}
// CapsMapFunc represents a function passed to the Caps MapInPlace, ForEach, and FilterAndMapInPlace methods.
type CapsMapFunc func(features *CapsFeatures, structure *Structure) bool
@@ -42,7 +68,7 @@ type CapsMapFunc func(features *CapsFeatures, structure *Structure) bool
// fmt.Println(caps.IsAny())
// // true
//
func NewAnyCaps() *Caps { return wrapCaps(C.gst_caps_new_any()) }
func NewAnyCaps() *Caps { return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_new_any())) }
// NewEmptyCaps creates a new empty caps object. This is essentially the opposite of
// NewAnyCamps.
@@ -51,7 +77,7 @@ func NewAnyCaps() *Caps { return wrapCaps(C.gst_caps_new_any()) }
// fmt.Println(caps.IsEmpty())
// // true
//
func NewEmptyCaps() *Caps { return wrapCaps(C.gst_caps_new_empty()) }
func NewEmptyCaps() *Caps { return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_new_empty())) }
// NewEmptySimpleCaps returns a new empty caps object with the given media format.
//
@@ -63,7 +89,7 @@ func NewEmptySimpleCaps(mediaFormat string) *Caps {
cFormat := C.CString(mediaFormat)
defer C.free(unsafe.Pointer(cFormat))
caps := C.gst_caps_new_empty_simple(cFormat)
return wrapCaps(caps)
return FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// NewFullCaps creates a new caps from the given structures.
@@ -88,22 +114,18 @@ func NewCapsFromString(capsStr string) *Caps {
if caps == nil {
return nil
}
return wrapCaps(caps)
return FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// NewRawCaps returns new GstCaps with the given format, sample-rate, and channels.
func NewRawCaps(format string, rate, channels int) *Caps {
capsStr := fmt.Sprintf("audio/x-raw, format=%s, rate=%d, channels=%d", format, rate, channels)
return NewCapsFromString(capsStr)
}
func (c *Caps) unsafe() unsafe.Pointer { return unsafe.Pointer(c.native) }
// Unsafe returns an unsafe.Pointer to the underlying GstCaps.
func (c *Caps) Unsafe() unsafe.Pointer { return unsafe.Pointer(c.native) }
// ToGValue returns a GValue containing the given caps. Note that under unexpected circumstances in allocation
// this function can return nil. A reference to these caps is taken by the resulting value, so they are safe to
// unref if not needed anymore.
// unref if not needed anymore. This method is intended for producing values that are needed elsewhere. If you
// are not going to use the value, call Unset.
func (c *Caps) ToGValue() *glib.Value {
val, err := glib.ValueInit(glib.Type(C.getCapsType()))
val, err := glib.ValueInitUnowned(glib.Type(C.getCapsType()))
if err != nil {
return nil
}
@@ -116,18 +138,23 @@ func (c *Caps) ToGValue() *glib.Value {
// From this point on, until the caller calls Unref or MakeWritable, it is guaranteed that the caps object
// will not change. This means its structures won't change, etc. To use a Caps object, you must always have a
// refcount on it -- either the one made implicitly by e.g. NewSimpleCaps, or via taking one explicitly with
// this function.
func (c *Caps) Ref() { C.gst_caps_ref(c.Instance()) }
// this function. Note that when a function provided by these bindings returns caps, or they are converted
// through the FromGstCapsUnsafe methods, a ref is automatically taken if necessary and a runtime Finalizer
// is used to remove it.
func (c *Caps) Ref() *Caps {
C.gst_caps_ref(c.Instance())
return c
}
// Unref decreases the ref count on these caps by one.
func (c *Caps) Unref() { C.gst_caps_unref(c.Instance()) }
// Instance returns the native GstCaps instance
func (c *Caps) Instance() *C.GstCaps { return C.toGstCaps(c.unsafe()) }
func (c *Caps) Instance() *C.GstCaps { return C.toGstCaps(c.Unsafe()) }
// MakeWritable returns a writable copy of caps.
func (c *Caps) MakeWritable() *Caps {
return wrapCaps(C.makeCapsWritable(c.Instance()))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.makeCapsWritable(c.Instance())))
}
// String implements a stringer on a caps instance. This same string can be used for NewCapsFromString.
@@ -151,7 +178,7 @@ func (c *Caps) AppendStructureFull(st *Structure, features *CapsFeatures) {
// Append appends the given caps element to these caps. These caps take ownership
// over the given object. If either caps are ANY, the resulting caps will be ANY.
func (c *Caps) Append(caps *Caps) {
C.gst_caps_append(c.Instance(), caps.Instance())
C.gst_caps_append(c.Instance(), caps.Ref().Instance())
}
// CanIntersect tries intersecting these caps with those given and reports whether the result would not be empty.
@@ -166,10 +193,14 @@ func (c *Caps) CanIntersect(caps *Caps) bool {
// on to a reference to the data, you should use Ref.
//
// When you are finished with the caps, call Unref on it.
func (c *Caps) Copy() *Caps { return wrapCaps(C.gst_caps_copy(c.Instance())) }
func (c *Caps) Copy() *Caps {
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_copy(c.Instance())))
}
// CopyNth creates a new GstCaps and appends a copy of the nth structure contained in caps.
func (c *Caps) CopyNth(n uint) *Caps { return wrapCaps(C.gst_caps_copy_nth(c.Instance(), C.guint(n))) }
func (c *Caps) CopyNth(n uint) *Caps {
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_copy_nth(c.Instance(), C.guint(n))))
}
// FilterAndMapInPlace calls the provided function once for each structure and caps feature in the Caps.
// In contrast to ForEach, the function may modify the structure and features. In contrast to MapInPlace,
@@ -210,7 +241,9 @@ func (c *Caps) FilterAndMapInPlace(f CapsMapFunc) {
// returned caps will be the empty too and contain no structure at all.
//
// Calling this function with any caps is not allowed.
func (c *Caps) Fixate() *Caps { return wrapCaps(C.gst_caps_fixate(c.Instance())) }
func (c *Caps) Fixate() *Caps {
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_fixate(c.Ref().Instance())))
}
// ForEach calls the provided function once for each structure and caps feature in the GstCaps. The function must not
// modify the fields. There is an unresolved bug in this function currently and it is better to use MapInPlace instead.
@@ -269,13 +302,13 @@ const (
// Intersect creates a new Caps that contains all the formats that are common to both these caps and those given.
// Defaults to CapsIntersectZigZag mode.
func (c *Caps) Intersect(caps *Caps) *Caps {
return wrapCaps(C.gst_caps_intersect(c.Instance(), caps.Instance()))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_intersect(c.Instance(), caps.Instance())))
}
// IntersectFull creates a new Caps that contains all the formats that are common to both these caps those given.
// The order is defined by the CapsIntersectMode used.
func (c *Caps) IntersectFull(caps *Caps, mode CapsIntersectMode) *Caps {
return wrapCaps(C.gst_caps_intersect_full(c.Instance(), caps.Instance(), C.GstCapsIntersectMode(mode)))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_intersect_full(c.Instance(), caps.Instance(), C.GstCapsIntersectMode(mode))))
}
// IsAlwaysCompatible returns if this structure is always compatible with another if every media format that is in
@@ -320,6 +353,11 @@ func (c *Caps) IsSubsetStructure(structure *Structure) bool {
// IsSubsetStructureFull checks if the given structure is a subset of these caps with features.
func (c *Caps) IsSubsetStructureFull(structure *Structure, features *CapsFeatures) bool {
if features == nil {
return gobool(C.gst_caps_is_subset_structure_full(
c.Instance(), structure.Instance(), nil,
))
}
return gobool(C.gst_caps_is_subset_structure_full(
c.Instance(), structure.Instance(), features.Instance(),
))
@@ -347,19 +385,24 @@ func (c *Caps) MapInPlace(f CapsMapFunc) bool {
// The structures in the given caps are not copied -- they are transferred to a writable copy of these ones,
// and then those given are freed. If either caps are ANY, the resulting caps will be ANY.
func (c *Caps) Merge(caps *Caps) *Caps {
return wrapCaps(C.gst_caps_merge(c.Instance(), caps.Instance()))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_merge(c.Ref().Instance(), caps.Ref().Instance())))
}
// MergeStructure appends structure to caps if its not already expressed by caps.
func (c *Caps) MergeStructure(structure *Structure) *Caps {
return wrapCaps(C.gst_caps_merge_structure(c.Instance(), structure.Instance()))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_merge_structure(c.Ref().Instance(), structure.Instance())))
}
// MergeStructureFull appends structure with features to the caps if its not already expressed.
func (c *Caps) MergeStructureFull(structure *Structure, features *CapsFeatures) *Caps {
return wrapCaps(C.gst_caps_merge_structure_full(
c.Instance(), structure.Instance(), features.Instance(),
))
if features == nil {
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_merge_structure_full(
c.Ref().Instance(), structure.Instance(), nil,
)))
}
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_merge_structure_full(
c.Ref().Instance(), structure.Instance(), features.Instance(),
)))
}
// Normalize returns a Caps that represents the same set of formats as caps, but contains no lists.
@@ -378,11 +421,19 @@ func (c *Caps) RemoveStructureAt(idx uint) {
// SetFeaturesAt sets the CapsFeatures features for the structure at index.
func (c *Caps) SetFeaturesAt(idx uint, features *CapsFeatures) {
if features == nil {
C.gst_caps_set_features(c.Instance(), C.guint(idx), nil)
return
}
C.gst_caps_set_features(c.Instance(), C.guint(idx), features.Instance())
}
// SetFeaturesSimple sets the CapsFeatures for all the structures of these caps.
func (c *Caps) SetFeaturesSimple(features *CapsFeatures) {
if features == nil {
C.gst_caps_set_features_simple(c.Instance(), nil)
return
}
C.gst_caps_set_features_simple(c.Instance(), features.Instance())
}
@@ -410,7 +461,7 @@ func (c *Caps) SetValue(field string, val interface{}) {
//
// This method does not preserve the original order of caps.
func (c *Caps) Simplify() *Caps {
return wrapCaps(C.gst_caps_simplify(c.Instance()))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_simplify(c.Ref().Instance())))
}
// StealStructureAt retrieves the structure with the given index from the list of structures contained in caps.
@@ -421,7 +472,7 @@ func (c *Caps) StealStructureAt(idx uint) *Structure {
// Subtract subtracts the given caps from these.
func (c *Caps) Subtract(caps *Caps) *Caps {
return wrapCaps(C.gst_caps_subtract(c.Instance(), caps.Instance()))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_subtract(c.Instance(), caps.Instance())))
}
// Truncate discards all but the first structure from caps. Useful when fixating.
@@ -431,4 +482,6 @@ func (c *Caps) Subtract(caps *Caps) *Caps {
//
// Note that it is not guaranteed that the returned caps have exactly one structure. If caps is any or empty caps
// then then returned caps will be the same and contain no structure at all.
func (c *Caps) Truncate() *Caps { return wrapCaps(C.gst_caps_truncate(c.Instance())) }
func (c *Caps) Truncate() *Caps {
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_caps_truncate(c.Ref().Instance())))
}

View File

@@ -7,7 +7,6 @@ import "unsafe"
// Go casting of pre-baked caps features
var (
CapsFeaturesAny = wrapCapsFeatures(C.gst_caps_features_new_any())
CapsFeatureMemorySystemMemory string = C.GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY
)
@@ -99,7 +98,8 @@ func (c *CapsFeatures) Copy() *CapsFeatures {
return wrapCapsFeatures(C.gst_caps_features_copy(c.Instance()))
}
// Free frees the memory containing these features.
// Free frees the memory containing these features. Only call this if you
// do not intend to pass these features to other methods.
func (c *CapsFeatures) Free() { C.gst_caps_features_free(c.Instance()) }
// GetNth returns the feature at index.

View File

@@ -145,7 +145,7 @@ func (c *ChildProxy) GetChildByIndex(idx uint) *glib.Object {
if gobj == nil {
return nil
}
return &glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gobj))}
return glib.TransferFull(unsafe.Pointer(gobj))
}
// GetChildByName fetches a child by name. The virtual method's default implementation uses Object
@@ -160,7 +160,7 @@ func (c *ChildProxy) GetChildByName(name string) *glib.Object {
if gobj == nil {
return nil
}
return &glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gobj))}
return glib.TransferFull(unsafe.Pointer(gobj))
}
// GetChildrenCount returns the number of child objects the parent contains.
@@ -198,7 +198,7 @@ func (c *ChildProxy) Lookup(name string) (ok bool, target *glib.Object, param *g
if !ok {
return
}
target = &glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gtarget))}
target = glib.TransferFull(unsafe.Pointer(gtarget))
param = glib.ToParamSpec(unsafe.Pointer(gspec))
return
}

View File

@@ -20,6 +20,7 @@ void clockDestroyNotify (gpointer user_data)
import "C"
import (
"runtime"
"time"
"unsafe"
@@ -41,7 +42,7 @@ func (c *ClockID) Instance() C.GstClockID { return c.ptr }
// GetClock returns the clock for this ClockID.
func (c *ClockID) GetClock() *Clock {
clk := C.gst_clock_id_get_clock(c.Instance())
return wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(clk))})
return FromGstClockUnsafeFull(unsafe.Pointer(clk))
}
// GetTime returns the time for this ClockID
@@ -122,6 +123,18 @@ func (c *ClockID) Unref() {
// Clock is a go wrapper around a GstClock.
type Clock struct{ *Object }
// FromGstClockUnsafeNone takes a pointer to a GstClock and wraps it in a Clock instance.
// A ref is taken on the clock and a finalizer applied.
func FromGstClockUnsafeNone(clock unsafe.Pointer) *Clock {
return wrapClock(glib.TransferNone(clock))
}
// FromGstClockUnsafeFull takes a pointer to a GstClock and wraps it in a Clock instance.
// A finalizer is set on the returned object.
func FromGstClockUnsafeFull(clock unsafe.Pointer) *Clock {
return wrapClock(glib.TransferFull(clock))
}
// Instance returns the underlying GstClock instance.
func (c *Clock) Instance() *C.GstClock { return C.toGstClock(c.Unsafe()) }
@@ -216,7 +229,7 @@ func (c *Clock) GetMaster() *Clock {
if clock == nil {
return nil
}
return wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(clock))})
return FromGstClockUnsafeFull(unsafe.Pointer(clock))
}
// GetResolution gets the accuracy of the clock. The accuracy of the clock is the granularity
@@ -241,7 +254,9 @@ func (c *Clock) NewPeriodicID(startTime, interval time.Duration) *ClockID {
C.GstClockTime(startTime),
C.GstClockTime(interval),
)
return &ClockID{id}
clkid := &ClockID{id}
runtime.SetFinalizer(clkid, (*ClockID).Unref)
return clkid
}
// NewSingleShotID gets a ClockID from the clock to trigger a single shot notification at the requested time.
@@ -251,7 +266,9 @@ func (c *Clock) NewSingleShotID(at time.Duration) *ClockID {
c.Instance(),
C.GstClockTime(at),
)
return &ClockID{id}
clkid := &ClockID{id}
runtime.SetFinalizer(clkid, (*ClockID).Unref)
return clkid
}
// PeriodicIDReinit reinitializes the provided periodic id to the provided start time and interval. Does not
@@ -285,6 +302,9 @@ func (c *Clock) SetCalibration(internal, external, rateNum, rateDenom time.Durat
// Master can be nil in which case clock will not be slaved anymore. It will however keep reporting its time
// adjusted with the last configured rate and time offsets.
func (c *Clock) SetMaster(master *Clock) bool {
if master == nil {
return gobool(C.gst_clock_set_master(c.Instance(), nil))
}
return gobool(C.gst_clock_set_master(c.Instance(), master.Instance()))
}

View File

@@ -2,13 +2,31 @@ package gst
// #include "gst.go.h"
import "C"
import "unsafe"
import (
"runtime"
"unsafe"
)
// Context wraps a GstContext object.
type Context struct {
ptr *C.GstContext
}
// FromGstContextUnsafeFull wraps the given context and places a runtime finalizer on it.
func FromGstContextUnsafeFull(ctx unsafe.Pointer) *Context {
wrapped := wrapContext((*C.GstContext)(ctx))
runtime.SetFinalizer(wrapped, (*Context).Unref)
return wrapped
}
// FromGstContextUnsafeNone refs and wraps the given context and places a runtime finalizer on it.
func FromGstContextUnsafeNone(ctx unsafe.Pointer) *Context {
wrapped := wrapContext((*C.GstContext)(ctx))
wrapped.Ref()
runtime.SetFinalizer(wrapped, (*Context).Unref)
return wrapped
}
// NewContext creates a new context.
//
// // Example
@@ -29,7 +47,7 @@ func NewContext(ctxType string, persistent bool) *Context {
if ctx == nil {
return nil
}
return wrapContext(ctx)
return FromGstContextUnsafeFull(unsafe.Pointer(ctx))
}
// Instance returns the underlying GstContext instance.
@@ -89,7 +107,7 @@ func (c *Context) IsWritable() bool {
// MakeWritable returns a writable version of the context.
func (c *Context) MakeWritable() *Context {
return wrapContext(C.makeContextWritable(c.Instance()))
return FromGstContextUnsafeFull(unsafe.Pointer(C.makeContextWritable(c.Instance())))
}
// WritableStructure returns a writable version of the structure. You should still not unref it.
@@ -100,3 +118,12 @@ func (c *Context) WritableStructure() *Structure {
}
return wrapStructure(st)
}
// Ref increases the ref count on the Context.
func (c *Context) Ref() *Context {
ctx := C.gst_context_ref(c.Instance())
return &Context{ptr: ctx}
}
// Unref decreases the ref count on the Context.
func (c *Context) Unref() { C.gst_context_unref(c.Instance()) }

View File

@@ -14,6 +14,16 @@ import (
// Device is a Go representation of a GstDevice.
type Device struct{ *Object }
// FromGstDeviceUnsafeNone wraps the given device with a ref and finalizer.
func FromGstDeviceUnsafeNone(device unsafe.Pointer) *Device {
return &Device{wrapObject(glib.TransferNone(device))}
}
// FromGstDeviceUnsafeFull wraps the given device with a finalizer.
func FromGstDeviceUnsafeFull(device unsafe.Pointer) *Device {
return &Device{wrapObject(glib.TransferFull(device))}
}
// Instance returns the underlying GstDevice object.
func (d *Device) Instance() *C.GstDevice { return C.toGstDevice(d.Unsafe()) }
@@ -26,33 +36,44 @@ func (d *Device) CreateElement(name string) *Element {
defer C.free(unsafe.Pointer(cName))
}
elem := C.gst_device_create_element(d.Instance(), cName)
return wrapElement(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(elem))})
if elem == nil {
return nil
}
return FromGstElementUnsafeNone(unsafe.Pointer(elem))
}
// Caps returns the caps that this device supports. Unref after usage.
func (d *Device) Caps() *Caps {
return wrapCaps(C.gst_device_get_caps(d.Instance()))
// GetCaps returns the caps that this device supports. Unref after usage.
func (d *Device) GetCaps() *Caps {
caps := C.gst_device_get_caps(d.Instance())
if caps == nil {
return nil
}
return FromGstCapsUnsafeNone(unsafe.Pointer(caps))
}
// DeviceClass gets the "class" of a device. This is a "/" separated list of classes that
// GetDeviceClass gets the "class" of a device. This is a "/" separated list of classes that
// represent this device. They are a subset of the classes of the GstDeviceProvider that produced
// this device.
func (d *Device) DeviceClass() string {
func (d *Device) GetDeviceClass() string {
class := C.gst_device_get_device_class(d.Instance())
defer C.g_free((C.gpointer)(unsafe.Pointer(class)))
return C.GoString(class)
}
// DisplayName gets the user-friendly name of the device.
func (d *Device) DisplayName() string {
// GetDisplayName gets the user-friendly name of the device.
func (d *Device) GetDisplayName() string {
name := C.gst_device_get_display_name(d.Instance())
defer C.g_free((C.gpointer)(unsafe.Pointer(name)))
return C.GoString(name)
}
// Properties gets the extra properties of the device.
func (d *Device) Properties() *Structure {
return wrapStructure(C.gst_device_get_properties(d.Instance()))
// GetProperties gets the extra properties of the device.
func (d *Device) GetProperties() *Structure {
st := C.gst_device_get_properties(d.Instance())
if st == nil {
return nil
}
return wrapStructure(st)
}
// HasClasses checks if device matches all of the given classes.

View File

@@ -45,6 +45,22 @@ import (
// Element is a Go wrapper around a GstElement.
type Element struct{ *Object }
// FromGstElementUnsafeNone wraps the given element with a ref and a finalizer.
func FromGstElementUnsafeNone(elem unsafe.Pointer) *Element {
if elem == nil {
return nil
}
return &Element{Object: &Object{InitiallyUnowned: &glib.InitiallyUnowned{Object: glib.TransferNone(elem)}}}
}
// FromGstElementUnsafeFull wraps the given element with a finalizer.
func FromGstElementUnsafeFull(elem unsafe.Pointer) *Element {
if elem == nil {
return nil
}
return &Element{Object: &Object{InitiallyUnowned: &glib.InitiallyUnowned{Object: glib.TransferFull(elem)}}}
}
// ToElement returns an Element object for the given Object. It will work
// on either gst.Object or glib.Object interfaces.
func ToElement(obj interface{}) *Element {
@@ -198,12 +214,16 @@ func (e *Element) ErrorMessage(domain Domain, code ErrorCode, text, debug string
// MessageFull will post an error, warning, or info message on the bus from inside an element. Only to be used
// from plugins.
func (e *Element) MessageFull(msgType MessageType, domain Domain, code ErrorCode, text, debug, file, function string, line int) {
var cTxt, cDbg unsafe.Pointer
var cTxt, cDbg unsafe.Pointer = nil, nil
if text != "" {
cTxt = unsafe.Pointer(C.CString(text))
ctxtstr := C.CString(debug)
defer C.free(unsafe.Pointer(ctxtstr))
cTxt = unsafe.Pointer(C.g_strdup((*C.gchar)(unsafe.Pointer(ctxtstr))))
}
if debug != "" {
cDbg = unsafe.Pointer(C.CString(debug))
cdbgstr := C.CString(debug)
defer C.free(unsafe.Pointer(cdbgstr))
cDbg = unsafe.Pointer(C.g_strdup((*C.gchar)(unsafe.Pointer(cdbgstr))))
}
C.gst_element_message_full(
e.Instance(),
@@ -225,7 +245,7 @@ func (e *Element) GetBus() *Bus {
if bus == nil {
return nil
}
return wrapBus(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(bus))})
return FromGstBusUnsafeFull(unsafe.Pointer(bus))
}
// GetClock returns the Clock for this element. This is the clock as was last set with gst_element_set_clock.
@@ -235,7 +255,7 @@ func (e *Element) GetClock() *Clock {
if cClock == nil {
return nil
}
return wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(cClock))})
return FromGstClockUnsafeFull(unsafe.Pointer(cClock))
}
// GetFactory returns the factory that created this element. No refcounting is needed.
@@ -248,14 +268,30 @@ func (e *Element) GetFactory() *ElementFactory {
}
// GetPads retrieves a list of pads associated with the element.
func (e *Element) GetPads() []*Pad {
goList := glib.WrapList(uintptr(unsafe.Pointer(e.Instance().pads)))
out := make([]*Pad, 0)
goList.Foreach(func(item interface{}) {
pt := item.(unsafe.Pointer)
out = append(out, wrapPad(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(pt))}))
})
return out
func (e *Element) GetPads() ([]*Pad, error) {
iter := C.gst_element_iterate_pads(e.Instance())
if iter == nil {
return nil, nil
}
return iteratorToPadSlice(iter)
}
// GetSinkPads retrieves a list of sink pads associated with the element.
func (e *Element) GetSinkPads() ([]*Pad, error) {
iter := C.gst_element_iterate_sink_pads(e.Instance())
if iter == nil {
return nil, nil
}
return iteratorToPadSlice(iter)
}
// GetSrcPads retrieves a list of src pads associated with the element.
func (e *Element) GetSrcPads() ([]*Pad, error) {
iter := C.gst_element_iterate_src_pads(e.Instance())
if iter == nil {
return nil, nil
}
return iteratorToPadSlice(iter)
}
// GetPadTemplates retrieves a list of the pad templates associated with this element.
@@ -289,7 +325,7 @@ func (e *Element) GetStaticPad(name string) *Pad {
if pad == nil {
return nil
}
return wrapPad(toGObject(unsafe.Pointer(pad)))
return FromGstPadUnsafeFull(unsafe.Pointer(pad))
}
// Has returns true if this element has the given flags.
@@ -312,8 +348,14 @@ func (e *Element) Link(elem *Element) error {
// LinkFiltered wraps gst_element_link_filtered and link this element to the given one
// using the provided sink caps.
func (e *Element) LinkFiltered(elem *Element, caps *Caps) error {
if ok := C.gst_element_link_filtered((*C.GstElement)(e.Instance()), (*C.GstElement)(elem.Instance()), (*C.GstCaps)(caps.Instance())); !gobool(ok) {
func (e *Element) LinkFiltered(elem *Element, filter *Caps) error {
if filter == nil {
if ok := C.gst_element_link_filtered(e.Instance(), elem.Instance(), nil); !gobool(ok) {
return fmt.Errorf("Failed to link %s to %s with provided caps", e.GetName(), elem.GetName())
}
return nil
}
if ok := C.gst_element_link_filtered(e.Instance(), elem.Instance(), filter.Instance()); !gobool(ok) {
return fmt.Errorf("Failed to link %s to %s with provided caps", e.GetName(), elem.GetName())
}
return nil
@@ -377,7 +419,7 @@ func (e *Element) QueryPosition(format Format) (bool, int64) {
// This function takes ownership of the provided event so you should gst_event_ref it if you want to reuse the event
// after this call.
func (e *Element) SendEvent(ev *Event) bool {
return gobool(C.gst_element_send_event(e.Instance(), ev.Instance()))
return gobool(C.gst_element_send_event(e.Instance(), ev.Ref().Instance()))
}
// SetState sets the target state for this element.

View File

@@ -81,7 +81,7 @@ func (e *ElementClass) GetPadTemplate(name string) *PadTemplate {
if tmpl == nil {
return nil
}
return wrapPadTemplate(toGObject(unsafe.Pointer(tmpl)))
return FromGstPadTemplateUnsafeNone(unsafe.Pointer(tmpl))
}
// GetAllPadTemplates retrieves a slice of all the pad templates associated with this class.
@@ -101,11 +101,19 @@ func (e *ElementClass) GetAllPadTemplates() []*PadTemplate {
//
// `author` - Name and contact details of the author(s). Use \n to separate multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
func (e *ElementClass) SetMetadata(longname, classification, description, author string) {
lname := C.CString(longname)
class := C.CString(classification)
desc := C.CString(description)
auth := C.CString(description)
defer C.free(unsafe.Pointer(lname))
defer C.free(unsafe.Pointer(class))
defer C.free(unsafe.Pointer(desc))
defer C.free(unsafe.Pointer(auth))
C.gst_element_class_set_static_metadata(
e.Instance(),
(*C.gchar)(C.CString(longname)),
(*C.gchar)(C.CString(classification)),
(*C.gchar)(C.CString(description)),
(*C.gchar)(C.CString(author)),
(*C.gchar)(unsafe.Pointer(lname)),
(*C.gchar)(unsafe.Pointer(class)),
(*C.gchar)(unsafe.Pointer(desc)),
(*C.gchar)(unsafe.Pointer(auth)),
)
}

View File

@@ -10,10 +10,6 @@ import (
"github.com/tinyzimmer/go-glib/glib"
)
// FromGstElementUnsafe wraps the pointer to the given C GstElement with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstElementUnsafe(elem unsafe.Pointer) *Element { return wrapElement(toGObject(elem)) }
// NewElement creates a new element using the factory of the given name.
func NewElement(factory string) (*Element, error) {
return NewElementWithName(factory, "")
@@ -32,9 +28,9 @@ func NewElementWithName(factory string, name string) (*Element, error) {
elem = C.gst_element_factory_make((*C.gchar)(elemName), (*C.gchar)(cname))
}
if elem == nil {
return nil, fmt.Errorf("Could not create element: %s", name)
return nil, fmt.Errorf("Could not create element: %s", factory)
}
return wrapElement(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(elem))}), nil
return wrapElement(glib.TransferNone(unsafe.Pointer(elem))), nil
}
// NewElementMany is a convenience wrapper around building many GstElements in a
@@ -63,7 +59,7 @@ func Find(name string) *ElementFactory {
if factory == nil {
return nil
}
return wrapElementFactory(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(factory))})
return wrapElementFactory(glib.TransferFull(unsafe.Pointer(factory)))
}
// Instance returns the C GstFactory instance

View File

@@ -4,10 +4,9 @@ package gst
import "C"
import (
"runtime"
"time"
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
)
// Event is a go wrapper around a GstEvent.
@@ -15,9 +14,25 @@ type Event struct {
ptr *C.GstEvent
}
// FromGstEventUnsafe wraps the pointer to the given C GstEvent with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstEventUnsafe(ev unsafe.Pointer) *Event { return wrapEvent((*C.GstEvent)(ev)) }
// // FromGstEventUnsafe is an alias to FromGstEventUnsafeNone.
// func FromGstEventUnsafe(ev unsafe.Pointer) *Event { return FromGstEventUnsafeNone(ev) }
// FromGstEventUnsafeNone wraps the pointer to the given C GstEvent with the go type.
// A ref is taken and finalizer applied.
func FromGstEventUnsafeNone(ev unsafe.Pointer) *Event {
event := &Event{ptr: (*C.GstEvent)(ev)}
event.Ref()
runtime.SetFinalizer(event, (*Event).Unref)
return event
}
// FromGstEventUnsafeFull wraps the pointer to the given C GstEvent without taking a ref.
// A finalizer is applied.
func FromGstEventUnsafeFull(ev unsafe.Pointer) *Event {
event := &Event{ptr: (*C.GstEvent)(ev)}
runtime.SetFinalizer(event, (*Event).Unref)
return event
}
// Instance returns the underlying GstEvent instance.
func (e *Event) Instance() *C.GstEvent { return C.toGstEvent(unsafe.Pointer(e.ptr)) }
@@ -37,7 +52,9 @@ func (e *Event) Seqnum() uint32 {
}
// Copy copies the event using the event specific copy function.
func (e *Event) Copy() *Event { return wrapEvent(C.gst_event_copy(e.Instance())) }
func (e *Event) Copy() *Event {
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_copy(e.Instance())))
}
// CopySegment parses a segment event and copies the Segment into the location given by segment.
func (e *Event) CopySegment(segment *Segment) {
@@ -93,7 +110,7 @@ func (e *Event) ParseBufferSize() (format Format, minSize, maxSize int64, async
func (e *Event) ParseCaps() *Caps {
var caps *C.GstCaps
C.gst_event_parse_caps(e.Instance(), &caps)
return wrapCaps(caps)
return FromGstCapsUnsafeNone(unsafe.Pointer(caps))
}
// ParseFlushStop parses the FLUSH_STOP event and retrieve the reset_time member. Value reflects whether
@@ -235,14 +252,14 @@ func (e *Event) ParseStep() (format Format, amount uint64, rate float64, flush,
func (e *Event) ParseStream() *Stream {
var stream *C.GstStream
C.gst_event_parse_stream(e.Instance(), &stream)
return wrapStream(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(stream))})
return FromGstStreamUnsafeFull(unsafe.Pointer(stream))
}
// ParseStreamCollection parses a stream collection from the event.
func (e *Event) ParseStreamCollection() *StreamCollection {
stream := &C.GstStreamCollection{}
C.gst_event_parse_stream_collection(e.Instance(), &stream)
return wrapStreamCollection(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(stream))})
return FromGstStreamCollectionUnsafeFull(unsafe.Pointer(stream))
}
// ParseStreamFlags parses the stream flags from an event.
@@ -271,7 +288,7 @@ func (e *Event) ParseStreamStart() string {
func (e *Event) ParseTag() *TagList {
var out *C.GstTagList
C.gst_event_parse_tag(e.Instance(), &out)
return wrapTagList(out)
return FromGstTagListUnsafeNone(unsafe.Pointer(out))
}
// ParseTOC parses a TOC event and store the results in the given toc and updated locations.
@@ -279,7 +296,7 @@ func (e *Event) ParseTOC() (toc *TOC, updated bool) {
var out *C.GstToc
var gupdated C.gboolean
C.gst_event_parse_toc(e.Instance(), &out, &gupdated)
return wrapTOC(out), gobool(gupdated)
return FromGstTOCUnsafeFull(unsafe.Pointer(out)), gobool(gupdated)
}
// ParseTOCSelect parses a TOC select event and store the results in the given uid location.

View File

@@ -13,20 +13,20 @@ import (
//
// When the async flag is set, a thread boundary is preferred.
func NewBufferSizeEvent(format Format, minSize, maxSize int64, async bool) *Event {
return wrapEvent(C.gst_event_new_buffer_size(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_buffer_size(
C.GstFormat(format),
C.gint64(minSize),
C.gint64(maxSize),
gboolean(async),
))
)))
}
// NewCapsEvent creates a new CAPS event for caps. The caps event can only travel downstream synchronized with
// the buffer flow and contains the format of the buffers that will follow after the event.
func NewCapsEvent(caps *Caps) *Event {
return wrapEvent(C.gst_event_new_caps(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_caps(
caps.Instance(),
))
)))
}
// NewEOSEvent creates a new EOS event. The eos event can only travel downstream synchronized with the buffer flow.
@@ -38,7 +38,7 @@ func NewCapsEvent(caps *Caps) *Event {
// When all sinks have posted an EOS message, an EOS message is forwarded to the application.
//
// The EOS event itself will not cause any state transitions of the pipeline.
func NewEOSEvent() *Event { return wrapEvent(C.gst_event_new_eos()) }
func NewEOSEvent() *Event { return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_eos())) }
// NewFlushStartEvent allocates a new flush start event. The flush start event can be sent upstream and downstream and
// travels out-of-bounds with the dataflow.
@@ -50,7 +50,9 @@ func NewEOSEvent() *Event { return wrapEvent(C.gst_event_new_eos()) }
// Elements should unlock any blocking functions and exit their streaming functions as fast as possible when this event is received.
//
// This event is typically generated after a seek to flush out all queued data in the pipeline so that the new media is played as soon as possible.
func NewFlushStartEvent() *Event { return wrapEvent(C.gst_event_new_flush_start()) }
func NewFlushStartEvent() *Event {
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_flush_start()))
}
// NewFlushStopEvent allocates a new flush stop event. The flush stop event can be sent upstream and downstream and travels serialized with the
// dataflow. It is typically sent after sending a FLUSH_START event to make the pads accept data again.
@@ -59,17 +61,17 @@ func NewFlushStartEvent() *Event { return wrapEvent(C.gst_event_new_flush_start(
//
// This event is typically generated to complete a seek and to resume dataflow.
func NewFlushStopEvent(resetTime bool) *Event {
return wrapEvent(C.gst_event_new_flush_stop(gboolean(resetTime)))
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_flush_stop(gboolean(resetTime))))
}
// NewGapEvent creates a new GAP event. A gap event can be thought of as conceptually equivalent to a buffer to signal that there is no data for a
//certain amount of time. This is useful to signal a gap to downstream elements which may wait for data, such as muxers or mixers or overlays,
// especially for sparse streams such as subtitle streams.
func NewGapEvent(timestamp, duration time.Duration) *Event {
return wrapEvent(C.gst_event_new_gap(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_gap(
C.GstClockTime(timestamp.Nanoseconds()),
C.GstClockTime(duration.Nanoseconds()),
))
)))
}
// NewInstantRateChangeEvent creates a new instant-rate-change event. This event is sent by seek handlers (e.g. demuxers) when receiving a seek with the
@@ -104,16 +106,16 @@ func NewGapEvent(timestamp, duration time.Duration) *Event {
//
// The latency is mostly used in live sinks and is always expressed in the time format.
func NewLatencyEvent(latency time.Duration) *Event {
return wrapEvent(C.gst_event_new_latency(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_latency(
C.GstClockTime(latency.Nanoseconds()),
))
)))
}
// NewNavigationEvent creates a new navigation event from the given description. The event will take ownership of the structure.
func NewNavigationEvent(structure *Structure) *Event {
return wrapEvent(C.gst_event_new_navigation(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_navigation(
structure.Instance(),
))
)))
}
// NewProtectionEvent creates a new event containing information specific to a particular protection system (uniquely identified by system_id), by which that protection system
@@ -136,11 +138,11 @@ func NewProtectionEvent(systemID string, buffer *Buffer, origin string) *Event {
cOrigin := C.CString(origin)
defer C.free(unsafe.Pointer(cSystemID))
defer C.free(unsafe.Pointer(cOrigin))
return wrapEvent(C.gst_event_new_protection(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_protection(
(*C.gchar)(unsafe.Pointer(cSystemID)),
buffer.Instance(),
(*C.gchar)(unsafe.Pointer(cOrigin)),
))
)))
}
// NewQOSEvent allocates a new qos event with the given values. The QOS event is generated in an element that wants an upstream element to either reduce or increase its rate because of
@@ -164,18 +166,18 @@ func NewProtectionEvent(systemID string, buffer *Buffer, origin string) *Event {
//
// The application can use general event probes to intercept the QoS event and implement custom application specific QoS handling.
func NewQOSEvent(qType QOSType, proportion float64, diff ClockTimeDiff, timestamp time.Duration) *Event {
return wrapEvent(C.gst_event_new_qos(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_qos(
C.GstQOSType(qType),
C.gdouble(proportion),
C.GstClockTimeDiff(diff),
C.GstClockTime(timestamp.Nanoseconds()),
))
)))
}
// NewReconfigureEvent creates a new reconfigure event. The purpose of the reconfigure event is to travel upstream and make elements renegotiate their caps or reconfigure their buffer pools.
// This is useful when changing properties on elements or changing the topology of the pipeline.
func NewReconfigureEvent() *Event {
return wrapEvent(C.gst_event_new_reconfigure())
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_reconfigure()))
}
// NewSeekEvent allocates a new seek event with the given parameters.
@@ -198,7 +200,7 @@ func NewReconfigureEvent() *Event {
// It is not possible to seek relative to the current playback position, to do this, PAUSE the pipeline, query the current playback position with GST_QUERY_POSITION and update the playback segment
// current position with a GST_SEEK_TYPE_SET to the desired position.
func NewSeekEvent(rate float64, format Format, flags SeekFlags, startType SeekType, start int64, stopType SeekType, stop int64) *Event {
return wrapEvent(C.gst_event_new_seek(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_seek(
C.gdouble(rate),
C.GstFormat(format),
C.GstSeekFlags(flags),
@@ -206,7 +208,7 @@ func NewSeekEvent(rate float64, format Format, flags SeekFlags, startType SeekTy
C.gint64(start),
C.GstSeekType(stopType),
C.gint64(stop),
))
)))
}
// NewSegmentEvent creates a new SEGMENT event for segment. The segment event can only travel downstream synchronized with the buffer flow and contains timing information and playback properties
@@ -228,16 +230,16 @@ func NewSeekEvent(rate float64, format Format, flags SeekFlags, startType SeekTy
//
// time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
func NewSegmentEvent(segment *Segment) *Event {
return wrapEvent(C.gst_event_new_segment(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_segment(
segment.Instance(),
))
)))
}
// NewSegmentDoneEvent creates a new segment-done event. This event is sent by elements that finish playback of a segment as a result of a segment seek.
func NewSegmentDoneEvent(format Format, position int64) *Event {
return wrapEvent(C.gst_event_new_segment_done(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_segment_done(
C.GstFormat(format), C.gint64(position),
))
)))
}
// NewSelectStreamsEvent allocates a new select-streams event.
@@ -249,9 +251,9 @@ func NewSegmentDoneEvent(format Format, position int64) *Event {
//
// Note: The list of streams can not be empty.
func NewSelectStreamsEvent(streams []*Stream) *Event {
return wrapEvent(C.gst_event_new_select_streams(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_select_streams(
streamSliceToGlist(streams),
))
)))
}
// NewSinkMessageEvent creates a new sink-message event. The purpose of the sink-message event is to instruct a sink to post the message contained in the event
@@ -261,10 +263,10 @@ func NewSelectStreamsEvent(streams []*Stream) *Event {
func NewSinkMessageEvent(name string, msg *Message) *Event {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
return wrapEvent(C.gst_event_new_sink_message(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_sink_message(
(*C.gchar)(unsafe.Pointer(cName)),
msg.Instance(),
))
)))
}
// NewStepEvent createss a new step event. The purpose of the step event is to instruct a sink to skip amount (expressed in format) of media. It can be used to
@@ -277,13 +279,13 @@ func NewSinkMessageEvent(name string, msg *Message) *Event {
//
// The intermediate flag instructs the pipeline that this step operation is part of a larger step operation.
func NewStepEvent(format Format, amount uint64, rate float64, flush, intermediate bool) *Event {
return wrapEvent(C.gst_event_new_step(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_step(
C.GstFormat(format),
C.guint64(amount),
C.gdouble(rate),
gboolean(flush),
gboolean(intermediate),
))
)))
}
// NewStreamCollectionEvent creates a new STREAM_COLLECTION event. The stream collection event can only travel downstream synchronized with the buffer flow.
@@ -291,9 +293,9 @@ func NewStepEvent(format Format, amount uint64, rate float64, flush, intermediat
// Source elements, demuxers and other elements that manage collections of streams and post GstStreamCollection messages on the bus also send this event downstream
// on each pad involved in the collection, so that activation of a new collection can be tracked through the downstream data flow.
func NewStreamCollectionEvent(collection *StreamCollection) *Event {
return wrapEvent(C.gst_event_new_stream_collection(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_stream_collection(
collection.Instance(),
))
)))
}
// NewStreamGroupDoneEvent creates a new Stream Group Done event. The stream-group-done event can only travel downstream synchronized with the buffer flow. Elements
@@ -303,7 +305,7 @@ func NewStreamCollectionEvent(collection *StreamCollection) *Event {
// This event is followed by EOS at some point in the future, and is generally used when switching pads - to unblock downstream so that new pads can be exposed before
// sending EOS on the existing pads.
func NewStreamGroupDoneEvent(groupID uint) *Event {
return wrapEvent(C.gst_event_new_stream_group_done(C.guint(groupID)))
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_stream_group_done(C.guint(groupID))))
}
// NewStreamStartEvent creates a new STREAM_START event. The stream start event can only travel downstream synchronized with the buffer flow. It is expected to be the
@@ -320,9 +322,9 @@ func NewStreamGroupDoneEvent(groupID uint) *Event {
func NewStreamStartEvent(streamID string) *Event {
cName := C.CString(streamID)
defer C.free(unsafe.Pointer(cName))
return wrapEvent(C.gst_event_new_stream_start(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_stream_start(
(*C.gchar)(unsafe.Pointer(cName)),
))
)))
}
// NewTagEvent generates a metadata tag event from the given taglist.
@@ -330,16 +332,16 @@ func NewStreamStartEvent(streamID string) *Event {
// The scope of the taglist specifies if the taglist applies to the complete medium or only to this specific stream. As the tag event is a sticky event, elements should merge
// tags received from upstream with a given scope with their own tags with the same scope and create a new tag event from it.
func NewTagEvent(tagList *TagList) *Event {
return wrapEvent(C.gst_event_new_tag(
tagList.Instance(),
))
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_tag(
tagList.Ref().Instance(),
)))
}
// NewTOCEvent generates a TOC event from the given toc. The purpose of the TOC event is to inform elements that some kind of the TOC was found.
func NewTOCEvent(toc *TOC, updated bool) *Event {
return wrapEvent(C.gst_event_new_toc(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_toc(
toc.Instance(), gboolean(updated),
))
)))
}
// NewTOCSelectEvent generates a TOC select event with the given uid. The purpose of the TOC select event is to start playback based on the TOC's
@@ -347,15 +349,15 @@ func NewTOCEvent(toc *TOC, updated bool) *Event {
func NewTOCSelectEvent(uid string) *Event {
cUID := C.CString(uid)
defer C.free(unsafe.Pointer(cUID))
return wrapEvent(C.gst_event_new_toc_select(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_toc_select(
(*C.gchar)(unsafe.Pointer(cUID)),
))
)))
}
// NewCustomEvent creates a new custom-typed event. This can be used for anything not handled by other event-specific functions to pass an event
// to another element.
func NewCustomEvent(eventType EventType, structure *Structure) *Event {
return wrapEvent(C.gst_event_new_custom(
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_new_custom(
C.GstEventType(eventType), structure.Instance(),
))
)))
}

View File

@@ -3,12 +3,26 @@ package gst
// #include "gst.go.h"
import "C"
import (
"runtime"
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
)
// GhostPad is a go representation of a GstGhostPad.
type GhostPad struct{ *ProxyPad }
// FromGstGhostPadUnsafeNone wraps the given GstGhostPad.
func FromGstGhostPadUnsafeNone(pad unsafe.Pointer) *GhostPad {
return &GhostPad{&ProxyPad{&Pad{wrapObject(glib.TransferNone(pad))}}}
}
// FromGstGhostPadUnsafeFull wraps the given GstGhostPad.
func FromGstGhostPadUnsafeFull(pad unsafe.Pointer) *GhostPad {
return &GhostPad{&ProxyPad{&Pad{wrapObject(glib.TransferFull(pad))}}}
}
// NewGhostPad create a new ghostpad with target as the target. The direction will be
// taken from the target pad. The target must be unlinked. If name is empty, one will be
// selected.
@@ -28,7 +42,7 @@ func NewGhostPad(name string, target *Pad) *GhostPad {
if pad == nil {
return nil
}
return wrapGhostPad(toGObject(unsafe.Pointer(pad)))
return FromGstGhostPadUnsafeNone(unsafe.Pointer(pad))
}
// NewGhostPadFromTemplate creates a new ghostpad with target as the target. The direction will be taken
@@ -51,7 +65,7 @@ func NewGhostPadFromTemplate(name string, target *Pad, tmpl *PadTemplate) *Ghost
if pad == nil {
return nil
}
return wrapGhostPad(toGObject(unsafe.Pointer(pad)))
return FromGstGhostPadUnsafeNone(unsafe.Pointer(pad))
}
// NewGhostPadNoTarget creates a new ghostpad without a target with the given direction. A target can be set on the
@@ -72,7 +86,7 @@ func NewGhostPadNoTarget(name string, direction PadDirection) *GhostPad {
if pad == nil {
return nil
}
return wrapGhostPad(toGObject(unsafe.Pointer(pad)))
return FromGstGhostPadUnsafeNone(unsafe.Pointer(pad))
}
// NewGhostPadNoTargetFromTemplate creates a new ghostpad based on templ, without setting a target. The direction will be taken
@@ -91,7 +105,7 @@ func NewGhostPadNoTargetFromTemplate(name string, tmpl *PadTemplate) *GhostPad {
if pad == nil {
return nil
}
return wrapGhostPad(toGObject(unsafe.Pointer(pad)))
return FromGstGhostPadUnsafeNone(unsafe.Pointer(pad))
}
// Instance returns the underlying ghost pad instance.
@@ -103,7 +117,7 @@ func (g *GhostPad) GetTarget() *Pad {
if pad == nil {
return nil
}
return wrapPad(toGObject(unsafe.Pointer(pad)))
return FromGstPadUnsafeFull(unsafe.Pointer(pad))
}
// SetTarget sets the new target of the ghostpad gpad. Any existing target is unlinked and links to the new target are
@@ -116,6 +130,11 @@ func (g *GhostPad) SetTarget(target *Pad) bool {
// ActivateModeDefault invokes the default activate mode function of a ghost pad.
func (g *GhostPad) ActivateModeDefault(parent *Object, mode PadMode, active bool) bool {
if parent == nil {
return gobool(C.gst_ghost_pad_activate_mode_default(
C.toGstPad(g.Unsafe()), nil, C.GstPadMode(mode), gboolean(active),
))
}
return gobool(C.gst_ghost_pad_activate_mode_default(
C.toGstPad(g.Unsafe()), parent.Instance(), C.GstPadMode(mode), gboolean(active),
))
@@ -123,6 +142,11 @@ func (g *GhostPad) ActivateModeDefault(parent *Object, mode PadMode, active bool
// InternalActivateModeDefault invokes the default activate mode function of a proxy pad that is owned by a ghost pad.
func (g *GhostPad) InternalActivateModeDefault(parent *Object, mode PadMode, active bool) bool {
if parent == nil {
return gobool(C.gst_ghost_pad_internal_activate_mode_default(
C.toGstPad(g.Unsafe()), nil, C.GstPadMode(mode), gboolean(active),
))
}
return gobool(C.gst_ghost_pad_internal_activate_mode_default(
C.toGstPad(g.Unsafe()), parent.Instance(), C.GstPadMode(mode), gboolean(active),
))
@@ -142,7 +166,9 @@ func (p *ProxyPad) Instance() *C.GstProxyPad { return C.toGstProxyPad(p.Unsafe()
// The internal pad of a GhostPad is the internally used pad of opposite direction, which is used to link to the target.
func (p *ProxyPad) GetInternal() *ProxyPad {
pad := C.gst_proxy_pad_get_internal(p.Instance())
return wrapProxyPad(toGObject(unsafe.Pointer(pad)))
proxyPad := wrapProxyPad(toGObject(unsafe.Pointer(pad)))
runtime.SetFinalizer(proxyPad, (*ProxyPad).Unref)
return proxyPad
}
// ChainDefault invokes the default chain function of the proxy pad.
@@ -160,7 +186,7 @@ func (p *ProxyPad) GetRangeDefault(parent *Object, offset uint64, size uint) (Fl
var buf *C.GstBuffer
ret := FlowReturn(C.gst_proxy_pad_getrange_default(p.toPad(), parent.Instance(), C.guint64(offset), C.guint(size), &buf))
if ret != FlowError {
return ret, wrapBuffer(buf)
return ret, FromGstBufferUnsafeFull(unsafe.Pointer(buf))
}
return ret, nil
}

View File

@@ -6,6 +6,7 @@ package gst
import "C"
import (
"runtime"
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
@@ -21,23 +22,42 @@ type Memory struct {
mapInfo *MapInfo
}
// FromGstMemoryUnsafe wraps the given C GstMemory in the go type. It is meant for internal usage
// and exported for visibility to other packages.
func FromGstMemoryUnsafe(mem unsafe.Pointer) *Memory {
wrapped := wrapMemory((*C.GstMemory)(mem))
wrapped.Ref()
runtime.SetFinalizer(wrapped, (*Memory).Unref)
return wrapped
}
// FromGstMemoryUnsafeNone is an alias to FromGstMemoryUnsafe.
func FromGstMemoryUnsafeNone(mem unsafe.Pointer) *Memory {
return FromGstMemoryUnsafe(mem)
}
// FromGstMemoryUnsafeFull wraps the given memory without taking an additional reference.
func FromGstMemoryUnsafeFull(mem unsafe.Pointer) *Memory {
wrapped := wrapMemory((*C.GstMemory)(mem))
runtime.SetFinalizer(wrapped, (*Memory).Unref)
return wrapped
}
// NewMemoryWrapped allocates a new memory block that wraps the given data.
//
// The prefix/padding must be filled with 0 if flags contains MemoryFlagZeroPrefixed
// and MemoryFlagZeroPadded respectively.
func NewMemoryWrapped(flags MemoryFlags, data []byte, maxSize, offset, size int64) *Memory {
str := string(data)
dataPtr := unsafe.Pointer(C.CString(str))
func NewMemoryWrapped(flags MemoryFlags, data []byte, maxSize, offset int64) *Memory {
mem := C.gst_memory_new_wrapped(
C.GstMemoryFlags(flags),
(C.gpointer)(dataPtr),
(C.gpointer)(unsafe.Pointer(&data[0])),
C.gsize(maxSize),
C.gsize(offset),
C.gsize(size),
C.gsize(len(data)),
nil, // TODO: Allow user to set userdata for destroy notify function
nil, // TODO: Allow user to set destroy notify function
)
return wrapMemory(mem)
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
}
// Instance returns the underlying GstMemory instance.
@@ -77,7 +97,7 @@ func (m *Memory) Size() int64 { return int64(m.Instance().size) }
// to the end of the memory region.
func (m *Memory) Copy(offset, size int64) *Memory {
mem := C.gst_memory_copy(m.Instance(), C.gssize(offset), C.gssize(size))
return wrapMemory(mem)
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
}
// Map the data inside the memory. This function can return nil if the memory is not read or writable.

View File

@@ -4,6 +4,7 @@ package gst
import "C"
import (
"runtime"
"strings"
"time"
"unsafe"
@@ -17,6 +18,23 @@ type Message struct {
msg *C.GstMessage
}
// FromGstMessageUnsafeNone wraps the given unsafe.Pointer in a message. A ref is taken
// on the message and a runtime finalizer placed on the object.
func FromGstMessageUnsafeNone(msg unsafe.Pointer) *Message {
gomsg := wrapMessage((*C.GstMessage)(msg))
gomsg.Ref()
runtime.SetFinalizer(gomsg, (*Message).Unref)
return gomsg
}
// FromGstMessageUnsafeFull wraps the given unsafe.Pointer in a message. No ref is taken
// and a finalizer is placed on the resulting object.
func FromGstMessageUnsafeFull(msg unsafe.Pointer) *Message {
gomsg := wrapMessage((*C.GstMessage)(msg))
runtime.SetFinalizer(gomsg, (*Message).Unref)
return gomsg
}
// Instance returns the underlying GstMessage object.
func (m *Message) Instance() *C.GstMessage { return C.toGstMessage(unsafe.Pointer(m.msg)) }
@@ -34,7 +52,7 @@ func (m *Message) Ref() *Message {
// Copy will copy this object into a new Message that can be Unrefed separately.
func (m *Message) Copy() *Message {
newNative := C.gst_message_copy((*C.GstMessage)(m.Instance()))
return wrapMessage(newNative)
return FromGstMessageUnsafeFull(unsafe.Pointer(newNative))
}
// Source returns the source of the message.
@@ -141,7 +159,7 @@ func (m *Message) ParseTags() *TagList {
if tagList == nil {
return nil
}
return wrapTagList(tagList)
return FromGstTagListUnsafeFull(unsafe.Pointer(tagList))
}
// ParseTOC extracts the TOC from the GstMessage. The TOC returned in the output argument is
@@ -150,7 +168,7 @@ func (m *Message) ParseTOC() (toc *TOC, updated bool) {
var gtoc *C.GstToc
var gupdated C.gboolean
C.gst_message_parse_toc(m.Instance(), &gtoc, &gupdated)
return wrapTOC(gtoc), gobool(gupdated)
return FromGstTOCUnsafeFull(unsafe.Pointer(gtoc)), gobool(gupdated)
}
// ParseStreamStatus parses the stream status type of the message as well as the element
@@ -163,7 +181,7 @@ func (m *Message) ParseStreamStatus() (StreamStatusType, *Element) {
(*C.GstStreamStatusType)(&cStatusType),
(**C.GstElement)(&cElem),
)
return StreamStatusType(cStatusType), wrapElement(toGObject(unsafe.Pointer(cElem)))
return StreamStatusType(cStatusType), FromGstElementUnsafeNone(unsafe.Pointer(cElem))
}
// ParseAsyncDone extracts the running time from the async task done message.
@@ -282,7 +300,7 @@ func (m *Message) ParseStepDone() *StepDoneValues {
func (m *Message) ParseNewClock() *Clock {
var clock *C.GstClock
C.gst_message_parse_new_clock((*C.GstMessage)(m.Instance()), &clock)
return wrapClock(toGObject(unsafe.Pointer(clock)))
return FromGstClockUnsafeNone(unsafe.Pointer(clock))
}
// ParseClockProvide extracts the clock and ready flag from the GstMessage.
@@ -291,7 +309,7 @@ func (m *Message) ParseClockProvide() (clock *Clock, ready bool) {
var gclock *C.GstClock
var gready C.gboolean
C.gst_message_parse_clock_provide((*C.GstMessage)(m.Instance()), &gclock, &gready)
return wrapClock(toGObject(unsafe.Pointer(clock))), gobool(gready)
return FromGstClockUnsafeNone(unsafe.Pointer(clock)), gobool(gready)
}
// ParseStructureChange extracts the change type and completion status from the GstMessage.
@@ -394,7 +412,7 @@ func (m *Message) ParseResetTime() time.Duration {
func (m *Message) ParseDeviceAdded() *Device {
var device *C.GstDevice
C.gst_message_parse_device_added((*C.GstMessage)(m.Instance()), &device)
return wrapDevice(toGObject(unsafe.Pointer(device)))
return FromGstDeviceUnsafeFull(unsafe.Pointer(device))
}
// ParseDeviceRemoved parses a device-removed message. The device-removed message
@@ -403,7 +421,7 @@ func (m *Message) ParseDeviceAdded() *Device {
func (m *Message) ParseDeviceRemoved() *Device {
var device *C.GstDevice
C.gst_message_parse_device_removed((*C.GstMessage)(m.Instance()), &device)
return wrapDevice(toGObject(unsafe.Pointer(device)))
return FromGstDeviceUnsafeFull(unsafe.Pointer(device))
}
// ParseDeviceChanged Parses a device-changed message. The device-changed message is
@@ -414,8 +432,8 @@ func (m *Message) ParseDeviceRemoved() *Device {
func (m *Message) ParseDeviceChanged() (newDevice, oldDevice *Device) {
var gstNewDevice, gstOldDevice *C.GstDevice
C.gst_message_parse_device_changed((*C.GstMessage)(m.Instance()), &gstNewDevice, &gstOldDevice)
return wrapDevice(toGObject(unsafe.Pointer(gstNewDevice))),
wrapDevice(toGObject(unsafe.Pointer(gstOldDevice)))
return FromGstDeviceUnsafeFull(unsafe.Pointer(gstNewDevice)),
FromGstDeviceUnsafeFull(unsafe.Pointer(gstOldDevice))
}
// ParsePropertyNotify parses a property-notify message. These will be posted on the bus only
@@ -441,7 +459,7 @@ func (m *Message) ParseStreamCollection() *StreamCollection {
(*C.GstMessage)(m.Instance()),
&collection,
)
return wrapStreamCollection(toGObject(unsafe.Pointer(collection)))
return FromGstStreamCollectionUnsafeFull(unsafe.Pointer(collection))
}
// ParseStreamsSelected parses a streams-selected message.
@@ -451,7 +469,7 @@ func (m *Message) ParseStreamsSelected() *StreamCollection {
(*C.GstMessage)(m.Instance()),
&collection,
)
return wrapStreamCollection(toGObject(unsafe.Pointer(collection)))
return FromGstStreamCollectionUnsafeFull(unsafe.Pointer(collection))
}
// NumRedirectEntries returns the number of redirect entries in a MessageRedirect.
@@ -474,12 +492,12 @@ func (m *Message) ParseRedirectEntryAt(idx int64) (location string, tags *TagLis
&entryStruct,
)
return string(C.GoBytes(locPtr, C.sizeOfGCharArray((**C.gchar)(locPtr)))),
wrapTagList(tagList), wrapStructure(entryStruct)
FromGstTagListUnsafeNone(unsafe.Pointer(tagList)), wrapStructure(entryStruct)
}
// ParseHaveContext parses the context from a HaveContext message.
func (m *Message) ParseHaveContext() *Context {
var ctx *C.GstContext
C.gst_message_parse_have_context(m.Instance(), &ctx)
return wrapContext(ctx)
return FromGstContextUnsafeFull(unsafe.Pointer(ctx))
}

View File

@@ -27,7 +27,7 @@ func NewApplicationMessage(src interface{}, structure *Structure) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_application(srcObj, structure.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_application(srcObj, structure.Instance())))
}
// NewAsyncDoneMessage builds a message that is posted when elements completed an ASYNC state change.
@@ -45,10 +45,10 @@ func NewAsyncDoneMessage(src interface{}, runningTime time.Duration) *Message {
} else {
cTime = C.GstClockTime(runningTime.Nanoseconds())
}
return wrapMessage(C.gst_message_new_async_done(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_async_done(
srcObj,
cTime,
))
)))
}
// NewAsyncStartMessage returns a message that is posted by elements when they start an ASYNC state change.
@@ -57,7 +57,7 @@ func NewAsyncStartMessage(src interface{}) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_async_start(srcObj))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_async_start(srcObj)))
}
// NewBufferingMessage returns a message that can be posted by an element that needs to buffer data before it
@@ -72,7 +72,7 @@ func NewBufferingMessage(src interface{}, percent int) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_buffering(srcObj, C.gint(percent)))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_buffering(srcObj, C.gint(percent))))
}
// NewClockLostMessage creates a clock lost message. This message is posted whenever the clock is not valid anymore.
@@ -84,7 +84,7 @@ func NewClockLostMessage(src interface{}, clock *Clock) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_clock_lost(srcObj, clock.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_clock_lost(srcObj, clock.Instance())))
}
// NewClockProvideMessage creates a clock provide message. This message is posted whenever an element is ready to provide a
@@ -96,7 +96,7 @@ func NewClockProvideMessage(src interface{}, clock *Clock, ready bool) *Message
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_clock_provide(srcObj, clock.Instance(), gboolean(ready)))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_clock_provide(srcObj, clock.Instance(), gboolean(ready))))
}
// NewCustomMessage creates a new custom-typed message. This can be used for anything not handled by other message-specific
@@ -107,9 +107,9 @@ func NewCustomMessage(src interface{}, msgType MessageType, structure *Structure
return nil
}
if structure == nil {
return wrapMessage(C.gst_message_new_custom(C.GstMessageType(msgType), srcObj, nil))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_custom(C.GstMessageType(msgType), srcObj, nil)))
}
return wrapMessage(C.gst_message_new_custom(C.GstMessageType(msgType), srcObj, structure.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_custom(C.GstMessageType(msgType), srcObj, structure.Instance())))
}
// NewDeviceAddedMessage creates a new device-added message. The device-added message is produced by a DeviceProvider or a DeviceMonitor.
@@ -119,7 +119,7 @@ func NewDeviceAddedMessage(src interface{}, device *Device) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_device_added(srcObj, device.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_device_added(srcObj, device.Instance())))
}
// NewDeviceChangedMessage creates a new device-changed message. The device-changed message is produced by a DeviceProvider or a DeviceMonitor.
@@ -129,7 +129,7 @@ func NewDeviceChangedMessage(src interface{}, device, changedDevice *Device) *Me
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_device_changed(srcObj, device.Instance(), changedDevice.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_device_changed(srcObj, device.Instance(), changedDevice.Instance())))
}
// NewDeviceRemovedMessage creates a new device-removed message. The device-removed message is produced by a DeviceProvider or a DeviceMonitor.
@@ -139,7 +139,7 @@ func NewDeviceRemovedMessage(src interface{}, device *Device) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_device_removed(srcObj, device.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_device_removed(srcObj, device.Instance())))
}
// NewDurationChangedMessage creates a new duration changed message. This message is posted by elements that know the duration of a
@@ -149,7 +149,7 @@ func NewDurationChangedMessage(src interface{}) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_duration_changed(srcObj))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_duration_changed(srcObj)))
}
// NewElementMessage creates a new element-specific message. This is meant as a generic way of allowing one-way communication from an
@@ -161,9 +161,9 @@ func NewElementMessage(src interface{}, structure *Structure) *Message {
return nil
}
if structure == nil {
return wrapMessage(C.gst_message_new_element(srcObj, nil))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_element(srcObj, nil)))
}
return wrapMessage(C.gst_message_new_element(srcObj, structure.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_element(srcObj, structure.Instance())))
}
// NewEOSMessage creates a new eos message. This message is generated and posted in the sink elements of a Bin. The bin will only forward
@@ -173,50 +173,40 @@ func NewEOSMessage(src interface{}) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_eos(srcObj))
}
func getErrorMessageParams(err *GError, debugStr string) (*C.GError, *C.gchar) {
var gdebugStr *C.char
if debugStr != "" {
gdebugStr = C.CString(debugStr)
}
errStr := C.CString(err.errMsg)
gerr := &C.GError{
code: C.gint(err.code),
message: (*C.gchar)(unsafe.Pointer(errStr)),
domain: C.guint(err.code),
}
return gerr, (*C.gchar)(unsafe.Pointer(gdebugStr))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_eos(srcObj)))
}
// NewErrorMessage creates a new error message. The message will copy error and debug. This message is posted by element when a fatal event
// occurred. The pipeline will probably (partially) stop. The application receiving this message should stop the pipeline.
// Structure can be nil to not add a structure to the message.
func NewErrorMessage(src interface{}, err *GError, debugStr string, structure *Structure) *Message {
func NewErrorMessage(src interface{}, err error, debugStr string, structure *Structure) *Message {
srcObj := getMessageSourceObj(src)
if srcObj == nil {
return nil
}
gerr, gdebugStr := getErrorMessageParams(err, debugStr)
errmsg := C.CString(err.Error())
gerr := C.g_error_new_literal(DomainLibrary.toQuark(), C.gint(LibraryErrorFailed), (*C.gchar)(errmsg))
defer C.free(unsafe.Pointer(errmsg))
defer C.g_error_free(gerr)
gdebugStr := C.CString(debugStr)
defer C.free(unsafe.Pointer(gdebugStr))
if structure != nil {
return wrapMessage(C.gst_message_new_error_with_details(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_error_with_details(
srcObj,
gerr,
gdebugStr,
structure.Instance(),
))
)))
}
return wrapMessage(C.gst_message_new_error(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_error(
srcObj,
gerr,
gdebugStr,
))
)))
}
// NewHaveContextMessage creates a message that is posted when an element has a new local Context.
@@ -225,35 +215,41 @@ func NewHaveContextMessage(src interface{}, ctx *Context) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_have_context(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_have_context(
srcObj,
ctx.Instance(),
))
ctx.Ref().Instance(),
)))
}
// NewInfoMessage creates a new info message. Structure can be nil.
func NewInfoMessage(src interface{}, err *GError, debugStr string, structure *Structure) *Message {
func NewInfoMessage(src interface{}, msg string, debugStr string, structure *Structure) *Message {
srcObj := getMessageSourceObj(src)
if srcObj == nil {
return nil
}
gerr, gdebugStr := getErrorMessageParams(err, debugStr)
errmsg := C.CString(msg)
gerr := C.g_error_new_literal(DomainLibrary.toQuark(), C.gint(0), (*C.gchar)(errmsg))
defer C.free(unsafe.Pointer(errmsg))
defer C.g_error_free(gerr)
gdebugStr := C.CString(debugStr)
defer C.free(unsafe.Pointer(gdebugStr))
if structure != nil {
return wrapMessage(C.gst_message_new_info_with_details(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_info_with_details(
srcObj,
gerr,
gdebugStr,
structure.Instance(),
))
)))
}
return wrapMessage(C.gst_message_new_info(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_info(
srcObj,
gerr,
gdebugStr,
))
)))
}
// NewLatencyMessage creates a message that can be posted by elements when their latency requirements have changed.
@@ -262,7 +258,7 @@ func NewLatencyMessage(src interface{}) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_latency(srcObj))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_latency(srcObj)))
}
// NewNeedContextMessage creates a message that is posted when an element needs a specific Context.
@@ -272,7 +268,7 @@ func NewNeedContextMessage(src interface{}, ctxType string) *Message {
return nil
}
cStr := C.CString(ctxType)
return wrapMessage(C.gst_message_new_need_context(srcObj, (*C.gchar)(unsafe.Pointer(cStr))))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_need_context(srcObj, (*C.gchar)(unsafe.Pointer(cStr)))))
}
// NewNewClockMessage creates a new clock message. This message is posted whenever the pipeline selects a new clock for the pipeline.
@@ -281,7 +277,7 @@ func NewNewClockMessage(src interface{}, clock *Clock) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_new_clock(srcObj, clock.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_new_clock(srcObj, clock.Instance())))
}
// NewProgressMessage creates messages that are posted by elements when they use an asynchronous task to perform actions triggered by a state change.
@@ -294,7 +290,7 @@ func NewProgressMessage(src interface{}, progressType ProgressType, code, text s
}
cCode := (*C.gchar)(unsafe.Pointer(C.CString(code)))
cText := (*C.gchar)(unsafe.Pointer(C.CString(text)))
return wrapMessage(C.gst_message_new_progress(srcObj, C.GstProgressType(progressType), cCode, cText))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_progress(srcObj, C.GstProgressType(progressType), cCode, cText)))
}
// NewPropertyNotifyMessage creates a new message notifying an object's properties have changed. If the
@@ -309,11 +305,11 @@ func NewPropertyNotifyMessage(src interface{}, propName string, val interface{})
return nil
}
cName := (*C.gchar)(unsafe.Pointer(C.CString(propName)))
return wrapMessage(C.gst_message_new_property_notify(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_property_notify(
srcObj,
cName,
(*C.GValue)(unsafe.Pointer(gVal.GValue)),
))
)))
}
// NewQoSMessage creates a message that is posted on the bus whenever an element decides to drop a buffer because of
@@ -329,14 +325,14 @@ func NewQoSMessage(src interface{}, live bool, runningTime, streamTime, timestam
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_qos(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_qos(
srcObj,
gboolean(live),
C.guint64((runningTime.Nanoseconds())),
C.guint64((streamTime.Nanoseconds())),
C.guint64((timestamp.Nanoseconds())),
C.guint64((duration.Nanoseconds())),
))
)))
}
// NewRedirectMessage creates a new redirect message and adds a new entry to it. Redirect messages are posted when an element detects that the actual
@@ -363,18 +359,20 @@ func NewRedirectMessage(src interface{}, location string, tagList *TagList, entr
var tl *C.GstTagList
var st *C.GstStructure
if location != "" {
loc = (*C.gchar)(unsafe.Pointer(C.CString(location)))
locc := C.CString(location)
defer C.free(unsafe.Pointer(locc))
loc = (*C.gchar)(unsafe.Pointer(locc))
}
if tagList != nil {
tl = tagList.Instance()
tl = tagList.Ref().Instance()
}
if entryStructure != nil {
st = entryStructure.Instance()
}
return wrapMessage(C.gst_message_new_redirect(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_redirect(
srcObj,
loc, tl, st,
))
)))
}
// AddRedirectEntry creates and appends a new entry to the message.
@@ -383,10 +381,12 @@ func (m *Message) AddRedirectEntry(location string, tagList *TagList, entryStruc
var tl *C.GstTagList
var st *C.GstStructure
if location != "" {
loc = (*C.gchar)(unsafe.Pointer(C.CString(location)))
locc := C.CString(location)
defer C.free(unsafe.Pointer(locc))
loc = (*C.gchar)(unsafe.Pointer(locc))
}
if tagList != nil {
tl = tagList.Instance()
tl = tagList.Ref().Instance()
}
if entryStructure != nil {
st = entryStructure.Instance()
@@ -401,7 +401,7 @@ func NewRequestStateMessage(src interface{}, state State) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_request_state(srcObj, C.GstState(state)))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_request_state(srcObj, C.GstState(state))))
}
// NewResetTimeMessage creates a message that is posted when the pipeline running-time should be reset to running_time, like after a flushing seek.
@@ -410,7 +410,7 @@ func NewResetTimeMessage(src interface{}, runningTime time.Duration) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_reset_time(srcObj, C.GstClockTime(runningTime.Nanoseconds())))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_reset_time(srcObj, C.GstClockTime(runningTime.Nanoseconds()))))
}
// NewSegmentDoneMessage creates a new segment done message. This message is posted by elements that finish playback of a segment as a result of a
@@ -420,11 +420,11 @@ func NewSegmentDoneMessage(src interface{}, format Format, position int64) *Mess
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_segment_done(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_segment_done(
srcObj,
C.GstFormat(format),
C.gint64(position),
))
)))
}
// NewSegmentStartMessage creates a new segment message. This message is posted by elements that start playback of a segment as a result of a segment seek.
@@ -434,11 +434,11 @@ func NewSegmentStartMessage(src interface{}, format Format, position int64) *Mes
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_segment_start(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_segment_start(
srcObj,
C.GstFormat(format),
C.gint64(position),
))
)))
}
// NewStateChangedMessage creates a state change message. This message is posted whenever an element changed its state.
@@ -447,10 +447,10 @@ func NewStateChangedMessage(src interface{}, oldState, newState, pendingState St
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_state_changed(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_state_changed(
srcObj,
C.GstState(oldState), C.GstState(newState), C.GstState(pendingState),
))
)))
}
// NewStateDirtyMessage creates a state dirty message. This message is posted whenever an element changed its state asynchronously
@@ -460,7 +460,7 @@ func NewStateDirtyMessage(src interface{}) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_state_dirty(srcObj))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_state_dirty(srcObj)))
}
// NewStepDoneMessage creates a message that is posted by elements when they complete a part, when intermediate set to TRUE, or a
@@ -472,7 +472,7 @@ func NewStepDoneMessage(src interface{}, format Format, amount uint64, rate floa
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_step_done(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_step_done(
srcObj,
C.GstFormat(format),
C.guint64(amount),
@@ -481,7 +481,7 @@ func NewStepDoneMessage(src interface{}, format Format, amount uint64, rate floa
gboolean(intermediate),
C.guint64(duration.Nanoseconds()),
gboolean(eos),
))
)))
}
// NewStepStartMessage creates a message that is posted by elements when they accept or activate a new step event for amount in format.
@@ -495,7 +495,7 @@ func NewStepStartMessage(src interface{}, active bool, format Format, amount uin
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_step_start(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_step_start(
srcObj,
gboolean(active),
C.GstFormat(format),
@@ -503,7 +503,7 @@ func NewStepStartMessage(src interface{}, active bool, format Format, amount uin
C.gdouble(rate),
gboolean(flush),
gboolean(intermediate),
))
)))
}
// NewStreamCollectionMessage creates a new stream-collection message. The message is used to announce new StreamCollections.
@@ -512,7 +512,7 @@ func NewStreamCollectionMessage(src interface{}, collection *StreamCollection) *
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_stream_collection(srcObj, collection.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_stream_collection(srcObj, collection.Instance())))
}
// NewStreamStartMessage creates a new stream_start message. This message is generated and posted in the sink elements of a Bin.
@@ -522,7 +522,7 @@ func NewStreamStartMessage(src interface{}) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_stream_start(srcObj))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_stream_start(srcObj)))
}
// NewStreamStatusMessage creates a new stream status message. This message is posted when a streaming thread is created/destroyed or
@@ -532,7 +532,7 @@ func NewStreamStatusMessage(src interface{}, stType StreamStatusType, owner *Ele
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_stream_status(srcObj, C.GstStreamStatusType(stType), owner.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_stream_status(srcObj, C.GstStreamStatusType(stType), owner.Instance())))
}
// NewStreamSelectedMessage creates a new steams-selected message. The message is used to announce that an array of streams has been selected.
@@ -546,7 +546,7 @@ func NewStreamSelectedMessage(src interface{}, collection *StreamCollection) *Me
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_streams_selected(srcObj, collection.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_streams_selected(srcObj, collection.Instance())))
}
// StreamsSelectedAdd adds the stream to the message
@@ -565,7 +565,7 @@ func (m *Message) StreamsSelectedGetStream(index uint) *Stream {
if stream == nil {
return nil
}
return wrapStream(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(stream))})
return wrapStream(glib.TransferFull(unsafe.Pointer(stream)))
}
// NewStructureChangeMessage creates a new structure change message. This message is posted when the structure of a pipeline is in the process
@@ -577,12 +577,12 @@ func NewStructureChangeMessage(src interface{}, chgType StructureChangeType, own
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_structure_change(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_structure_change(
srcObj,
C.GstStructureChangeType(chgType),
owner.Instance(),
gboolean(busy),
))
)))
}
// NewTagMessage creates a new tag message. The message will take ownership of the tag list. The message is posted by elements that discovered a new taglist.
@@ -591,7 +591,7 @@ func NewTagMessage(src interface{}, tagList *TagList) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_tag(srcObj, tagList.Instance()))
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_tag(srcObj, tagList.Ref().Instance())))
}
// NewTOCMessage creates a new TOC message. The message is posted by elements that discovered or updated a TOC.
@@ -600,21 +600,27 @@ func NewTOCMessage(src interface{}, toc *TOC, updated bool) *Message {
if srcObj == nil {
return nil
}
return wrapMessage(C.gst_message_new_toc(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_toc(
srcObj,
toc.Instance(),
gboolean(updated),
))
)))
}
// NewWarningMessage creates a new warning message. Structure can be nil.
func NewWarningMessage(src interface{}, err *GError, debugStr string, structure *Structure) *Message {
func NewWarningMessage(src interface{}, msg string, debugStr string, structure *Structure) *Message {
srcObj := getMessageSourceObj(src)
if srcObj == nil {
return nil
}
gerr, gdebugStr := getErrorMessageParams(err, debugStr)
errmsg := C.CString(msg)
gerr := C.g_error_new_literal(DomainLibrary.toQuark(), C.gint(0), (*C.gchar)(errmsg))
defer C.free(unsafe.Pointer(errmsg))
defer C.g_error_free(gerr)
gdebugStr := C.CString(debugStr)
defer C.free(unsafe.Pointer(gdebugStr))
if structure != nil {
return wrapMessage(C.gst_message_new_warning_with_details(
@@ -625,9 +631,9 @@ func NewWarningMessage(src interface{}, err *GError, debugStr string, structure
))
}
return wrapMessage(C.gst_message_new_warning(
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_warning(
srcObj,
gerr,
gdebugStr,
))
)))
}

View File

@@ -147,17 +147,17 @@ func (m *Message) String() string {
case MessageDeviceAdded:
if device := m.ParseDeviceAdded(); device != nil {
msg += fmt.Sprintf("Device %s added", device.DisplayName())
msg += fmt.Sprintf("Device %s added", device.GetDisplayName())
}
case MessageDeviceRemoved:
if device := m.ParseDeviceRemoved(); device != nil {
msg += fmt.Sprintf("Device %s removed", device.DisplayName())
msg += fmt.Sprintf("Device %s removed", device.GetDisplayName())
}
case MessageDeviceChanged:
if device, _ := m.ParseDeviceChanged(); device != nil {
msg += fmt.Sprintf("Device %s had its properties updated", device.DisplayName())
msg += fmt.Sprintf("Device %s had its properties updated", device.GetDisplayName())
}
case MessagePropertyNotify:

View File

@@ -13,9 +13,13 @@ import (
// Object is a go representation of a GstObject.
type Object struct{ *glib.InitiallyUnowned }
// FromGstObjectUnsafe returns an Object wrapping the given pointer. It meant for internal
// FromGstObjectUnsafeNone returns an Object wrapping the given pointer. It meant for internal
// usage and exported for visibility to other packages.
func FromGstObjectUnsafe(ptr unsafe.Pointer) *Object { return wrapObject(toGObject(ptr)) }
func FromGstObjectUnsafeNone(ptr unsafe.Pointer) *Object { return wrapObject(glib.TransferNone(ptr)) }
// FromGstObjectUnsafeFull returns an Object wrapping the given pointer. It meant for internal
// usage and exported for visibility to other packages.
func FromGstObjectUnsafeFull(ptr unsafe.Pointer) *Object { return wrapObject(glib.TransferFull(ptr)) }
// Instance returns the native C GstObject.
func (o *Object) Instance() *C.GstObject { return C.toGstObject(o.Unsafe()) }

View File

@@ -114,6 +114,16 @@ func (p PadFuncMap) RemoveFuncForPad(pad unsafe.Pointer) {
// Pad is a go representation of a GstPad
type Pad struct{ *Object }
// FromGstPadUnsafeFull wraps the given pad in a reference and finalizer.
func FromGstPadUnsafeFull(pad unsafe.Pointer) *Pad {
return &Pad{wrapObject(glib.TransferFull(pad))}
}
// FromGstPadUnsafeNone wraps the given pad in a finalizer.
func FromGstPadUnsafeNone(pad unsafe.Pointer) *Pad {
return &Pad{wrapObject(glib.TransferNone(pad))}
}
// NewPad returns a new pad with the given direction. If name is empty, one will be generated for you.
func NewPad(name string, direction PadDirection) *Pad {
var cName *C.gchar
@@ -126,7 +136,7 @@ func NewPad(name string, direction PadDirection) *Pad {
if pad == nil {
return nil
}
return wrapPad(toGObject(unsafe.Pointer(pad)))
return FromGstPadUnsafeNone(unsafe.Pointer(pad))
}
// NewPadFromTemplate creates a new pad with the given name from the given template. If name is empty, one will
@@ -142,13 +152,9 @@ func NewPadFromTemplate(tmpl *PadTemplate, name string) *Pad {
if pad == nil {
return nil
}
return wrapPad(toGObject(unsafe.Pointer(pad)))
return FromGstPadUnsafeNone(unsafe.Pointer(pad))
}
// FromGstPadUnsafe wraps the given pointer in a Pad object. It is meant for internal usage and exported for
// visibility to other packages.
func FromGstPadUnsafe(pad unsafe.Pointer) *Pad { return wrapPad(toGObject(pad)) }
// Instance returns the underlying C GstPad.
func (p *Pad) Instance() *C.GstPad { return C.toGstPad(p.Unsafe()) }
@@ -168,7 +174,7 @@ func (p *Pad) CurrentCaps() *Caps {
if caps == nil {
return nil
}
return wrapCaps(caps)
return FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// ActivateMode activates or deactivates the given pad in mode via dispatching to the pad's activatemodefunc.
@@ -217,7 +223,7 @@ func (p *Pad) CanLink(sink *Pad) bool {
//
// In all cases, success or failure, the caller loses its reference to buffer after calling this function.
func (p *Pad) Chain(buffer *Buffer) FlowReturn {
return FlowReturn(C.gst_pad_chain(p.Instance(), buffer.Instance()))
return FlowReturn(C.gst_pad_chain(p.Instance(), buffer.Ref().Instance()))
}
// ChainList chains a bufferlist to pad.
@@ -231,7 +237,7 @@ func (p *Pad) Chain(buffer *Buffer) FlowReturn {
//
// In all cases, success or failure, the caller loses its reference to list after calling this function.
func (p *Pad) ChainList(bufferList *BufferList) FlowReturn {
return FlowReturn(C.gst_pad_chain_list(p.Instance(), bufferList.Instance()))
return FlowReturn(C.gst_pad_chain_list(p.Instance(), bufferList.Ref().Instance()))
}
// CheckReconfigure checks and clear the PadFlagNeedReconfigure flag on pad and return TRUE if the flag was set.
@@ -270,7 +276,10 @@ func (p *Pad) CreateStreamID(parent *Element, streamID string) string {
//
// The event is sent to all pads internally linked to pad. This function takes ownership of event.
func (p *Pad) EventDefault(parent *Object, event *Event) bool {
return gobool(C.gst_pad_event_default(p.Instance(), parent.Instance(), event.Instance()))
if parent == nil {
return gobool(C.gst_pad_event_default(p.Instance(), nil, event.Ref().Instance()))
}
return gobool(C.gst_pad_event_default(p.Instance(), parent.Instance(), event.Ref().Instance()))
}
// PadForwardFunc is called for all internally linked pads, see Pad Forward().
@@ -296,16 +305,16 @@ func (p *Pad) Forward(f PadForwardFunc) bool {
// The allowed capabilities is calculated as the intersection of the results of calling QueryCaps on pad and its peer. The caller owns a reference on the
// resulting caps.
func (p *Pad) GetAllowedCaps() *Caps {
return wrapCaps(C.gst_pad_get_allowed_caps(
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_pad_get_allowed_caps(
p.Instance(),
))
)))
}
// GetCurrentCaps gets the capabilities currently configured on pad with the last EventCaps event.
func (p *Pad) GetCurrentCaps() *Caps {
return wrapCaps(C.gst_pad_get_current_caps(
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_pad_get_current_caps(
p.Instance(),
))
)))
}
// GetDirection gets the direction of the pad. The direction of the pad is decided at construction time so this function does not take the LOCK.
@@ -337,7 +346,7 @@ func (p *Pad) GetPadTemplate() *PadTemplate {
if tmpl == nil {
return nil
}
return wrapPadTemplate(toGObject(unsafe.Pointer(tmpl)))
return FromGstPadTemplateUnsafeFull(unsafe.Pointer(tmpl))
}
// GetPadTemplateCaps gets the capabilities for pad's template.
@@ -346,7 +355,7 @@ func (p *Pad) GetPadTemplateCaps() *Caps {
if caps == nil {
return nil
}
return wrapCaps(caps)
return FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// GetParentElement gets the parent of pad, cast to a Element. If a pad has no parent or its
@@ -356,7 +365,7 @@ func (p *Pad) GetParentElement() *Element {
if elem == nil {
return nil
}
return wrapElement(toGObject(unsafe.Pointer(elem)))
return FromGstElementUnsafeFull(unsafe.Pointer(elem))
}
// GetPeer gets the peer of pad. This function refs the peer pad so you need to unref it after use.
@@ -365,7 +374,7 @@ func (p *Pad) GetPeer() *Pad {
if peer == nil {
return nil
}
return wrapPad(toGObject(unsafe.Pointer(peer)))
return FromGstPadUnsafeFull(unsafe.Pointer(peer))
}
// GetRange calls the getrange function of pad, see PadGetRangeFunc for a description of a getrange function.
@@ -406,7 +415,7 @@ func (p *Pad) GetStickyEvent(eventType EventType, idx uint) *Event {
if ev == nil {
return nil
}
return wrapEvent(ev)
return FromGstEventUnsafeFull(unsafe.Pointer(ev))
}
// GetStream returns the current Stream for the pad, or nil if none has been set yet, i.e. the pad has not received a
@@ -418,7 +427,7 @@ func (p *Pad) GetStream() *Stream {
if st == nil {
return nil
}
return wrapStream(toGObject(unsafe.Pointer(st)))
return FromGstStreamUnsafeFull(unsafe.Pointer(st))
}
// GetStreamID returns the current stream-id for the pad, or an empty string if none has been set yet, i.e. the pad has not received
@@ -566,7 +575,7 @@ func (p *Pad) PeerQueryCaps(filter *Caps) *Caps {
if caps == nil {
return nil
}
return wrapCaps(caps)
return FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// PeerQueryConvert queries the peer pad of a given sink pad to convert src_val in src_format to dest_format.
@@ -630,7 +639,7 @@ func (p *Pad) PullRange(offset uint64, size uint, buffer *Buffer) (FlowReturn, *
ret := C.gst_pad_pull_range(p.Instance(), C.guint64(offset), C.guint(size), &buf)
var newBuf *Buffer
if buf != nil {
newBuf = wrapBuffer(buf)
newBuf = FromGstBufferUnsafeFull(unsafe.Pointer(buf))
} else {
newBuf = nil
}
@@ -645,14 +654,14 @@ func (p *Pad) PullRange(offset uint64, size uint, buffer *Buffer) (FlowReturn, *
//
// In all cases, success or failure, the caller loses its reference to buffer after calling this function.
func (p *Pad) Push(buf *Buffer) FlowReturn {
return FlowReturn(C.gst_pad_push(p.Instance(), buf.Instance()))
return FlowReturn(C.gst_pad_push(p.Instance(), buf.Ref().Instance()))
}
// PushEvent sends the event to the peer of the given pad. This function is mainly used by elements to send events to their peer elements.
//
// This function takes ownership of the provided event so you should Ref it if you want to reuse the event after this call.
func (p *Pad) PushEvent(ev *Event) bool {
return gobool(C.gst_pad_push_event(p.Instance(), ev.Instance()))
return gobool(C.gst_pad_push_event(p.Instance(), ev.Ref().Instance()))
}
// PushList pushes a buffer list to the peer of pad.
@@ -665,7 +674,7 @@ func (p *Pad) PushEvent(ev *Event) bool {
//
// In all cases, success or failure, the caller loses its reference to list after calling this function.
func (p *Pad) PushList(bufList *BufferList) FlowReturn {
return FlowReturn(C.gst_pad_push_list(p.Instance(), bufList.Instance()))
return FlowReturn(C.gst_pad_push_list(p.Instance(), bufList.Ref().Instance()))
}
// Query dispatches a query to a pad. The query should have been allocated by the caller via one of the type-specific allocation functions. The element that the
@@ -701,7 +710,7 @@ func (p *Pad) QueryCaps(filter *Caps) *Caps {
if caps == nil {
return nil
}
return wrapCaps(caps)
return FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// QueryConvert queries a pad to convert src_val in src_format to dest_format.
@@ -749,7 +758,7 @@ func (p *Pad) RemoveProbe(id uint64) {
//
// This function takes ownership of the provided event so you should gst_event_ref it if you want to reuse the event after this call.
func (p *Pad) SendEvent(ev *Event) bool {
return gobool(C.gst_pad_send_event(p.Instance(), ev.Instance()))
return gobool(C.gst_pad_send_event(p.Instance(), ev.Ref().Instance()))
}
func (p *Pad) registerCallback(f interface{}, fmap PadFuncMap) *C.PadDestroyNotifyInfo {
@@ -1080,7 +1089,7 @@ func (p *PadProbeInfo) GetBuffer() *Buffer {
if buf == nil {
return nil
}
return wrapBuffer(buf)
return FromGstBufferUnsafeNone(unsafe.Pointer(buf))
}
// GetBufferList returns the buffer list, if any, inside this probe info.
@@ -1089,7 +1098,7 @@ func (p *PadProbeInfo) GetBufferList() *BufferList {
if bufList == nil {
return nil
}
return wrapBufferList(bufList)
return FromGstBufferListUnsafeNone(unsafe.Pointer(bufList))
}
// GetEvent returns the event, if any, inside this probe info.
@@ -1098,7 +1107,7 @@ func (p *PadProbeInfo) GetEvent() *Event {
if ev == nil {
return nil
}
return wrapEvent(ev)
return FromGstEventUnsafeNone(unsafe.Pointer(ev))
}
// GetQuery returns the query, if any, inside this probe info.
@@ -1107,7 +1116,7 @@ func (p *PadProbeInfo) GetQuery() *Query {
if q == nil {
return nil
}
return wrapQuery(q)
return FromGstQueryUnsafeNone(unsafe.Pointer(q))
}
func iteratorToPadSlice(iterator *C.GstIterator) ([]*Pad, error) {
@@ -1124,10 +1133,10 @@ func iteratorToPadSlice(iterator *C.GstIterator) ([]*Pad, error) {
case C.GST_ITERATOR_OK:
cPadVoid := C.g_value_get_object((*C.GValue)(gval))
cPad := (*C.GstPad)(cPadVoid)
pads = append(pads, wrapPad(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(cPad))}))
pads = append(pads, FromGstPadUnsafeFull(unsafe.Pointer(cPad)))
C.g_value_reset((*C.GValue)(gval))
default:
return nil, errors.New("Element iterator failed")
return nil, errors.New("Pad iterator failed")
}
}
}

View File

@@ -55,7 +55,7 @@ func goGstPadActivateModeFunction(pad *C.GstPad, parent *C.GstObject, mode C.Gst
//export goGstPadChainFunction
func goGstPadChainFunction(pad *C.GstPad, parent *C.GstObject, buffer *C.GstBuffer) C.GstFlowReturn {
f := padChainFuncs.FuncForPad(unsafe.Pointer(pad)).(PadChainFunc)
buf := wrapBuffer(buffer)
buf := FromGstBufferUnsafeFull(unsafe.Pointer(buffer))
defer buf.Unref()
return C.GstFlowReturn(f(
wrapPad(toGObject(unsafe.Pointer(pad))),
@@ -67,7 +67,7 @@ func goGstPadChainFunction(pad *C.GstPad, parent *C.GstObject, buffer *C.GstBuff
//export goGstPadChainListFunction
func goGstPadChainListFunction(pad *C.GstPad, parent *C.GstObject, list *C.GstBufferList) C.GstFlowReturn {
f := padChainListFuncs.FuncForPad(unsafe.Pointer(pad)).(PadChainListFunc)
buflist := wrapBufferList(list)
buflist := FromGstBufferListUnsafeFull(unsafe.Pointer(list))
defer buflist.Unref()
return C.GstFlowReturn(f(
wrapPad(toGObject(unsafe.Pointer(pad))),
@@ -79,7 +79,7 @@ func goGstPadChainListFunction(pad *C.GstPad, parent *C.GstObject, list *C.GstBu
//export goGstPadEventFullFunction
func goGstPadEventFullFunction(pad *C.GstPad, parent *C.GstObject, event *C.GstEvent) C.GstFlowReturn {
f := padEventFullFuncs.FuncForPad(unsafe.Pointer(pad)).(PadEventFullFunc)
ev := wrapEvent(event)
ev := FromGstEventUnsafeFull(unsafe.Pointer(event))
defer ev.Unref()
return C.GstFlowReturn(f(
wrapPad(toGObject(unsafe.Pointer(pad))),
@@ -91,7 +91,7 @@ func goGstPadEventFullFunction(pad *C.GstPad, parent *C.GstObject, event *C.GstE
//export goGstPadEventFunction
func goGstPadEventFunction(pad *C.GstPad, parent *C.GstObject, event *C.GstEvent) C.gboolean {
f := padEventFuncs.FuncForPad(unsafe.Pointer(pad)).(PadEventFunc)
ev := wrapEvent(event)
ev := FromGstEventUnsafeFull(unsafe.Pointer(event))
defer ev.Unref()
return gboolean(f(
wrapPad(toGObject(unsafe.Pointer(pad))),

View File

@@ -11,6 +11,16 @@ import (
// PadTemplate is a go representation of a GstPadTemplate
type PadTemplate struct{ *Object }
// FromGstPadTemplateUnsafeNone wraps the given GstPadTemplate in a ref and a finalizer.
func FromGstPadTemplateUnsafeNone(tmpl unsafe.Pointer) *PadTemplate {
return &PadTemplate{wrapObject(glib.TransferNone(tmpl))}
}
// FromGstPadTemplateUnsafeFull wraps the given GstPadTemplate in a finalizer.
func FromGstPadTemplateUnsafeFull(tmpl unsafe.Pointer) *PadTemplate {
return &PadTemplate{wrapObject(glib.TransferFull(tmpl))}
}
// NewPadTemplate creates a new pad template with a name according to the given template and with the given arguments.
func NewPadTemplate(nameTemplate string, direction PadDirection, presence PadPresence, caps *Caps) *PadTemplate {
cName := C.CString(nameTemplate)
@@ -24,7 +34,7 @@ func NewPadTemplate(nameTemplate string, direction PadDirection, presence PadPre
if tmpl == nil {
return nil
}
return wrapPadTemplate(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(tmpl))})
return wrapPadTemplate(glib.TransferNone(unsafe.Pointer(tmpl)))
}
// NewPadTemplateWithGType creates a new pad template with a name according to the given template and with the given arguments.
@@ -41,7 +51,7 @@ func NewPadTemplateWithGType(nameTemplate string, direction PadDirection, presen
if tmpl == nil {
return nil
}
return wrapPadTemplate(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(tmpl))})
return wrapPadTemplate(glib.TransferNone(unsafe.Pointer(tmpl)))
}
// Instance returns the underlying C GstPadTemplate.
@@ -57,7 +67,9 @@ func (p *PadTemplate) Direction() PadDirection { return PadDirection(p.Instance(
func (p *PadTemplate) Presence() PadPresence { return PadPresence(p.Instance().presence) }
// Caps returns the caps of the pad template.
func (p *PadTemplate) Caps() *Caps { return wrapCaps(C.gst_pad_template_get_caps(p.Instance())) }
func (p *PadTemplate) Caps() *Caps {
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_pad_template_get_caps(p.Instance())))
}
// PadCreated emits the pad-created signal for this template when created by this pad.
func (p *PadTemplate) PadCreated(pad *Pad) {

View File

@@ -18,6 +18,16 @@ type Pipeline struct {
bus *Bus
}
// FromGstPipelineUnsafeFull wraps the given pipeline pointer.
func FromGstPipelineUnsafeFull(pipeline unsafe.Pointer) *Pipeline {
return &Pipeline{Bin: &Bin{&Element{wrapObject(glib.TransferFull(pipeline))}}}
}
// FromGstPipelineUnsafeNone wraps the given pipeline pointer.
func FromGstPipelineUnsafeNone(pipeline unsafe.Pointer) *Pipeline {
return &Pipeline{Bin: &Bin{&Element{wrapObject(glib.TransferNone(pipeline))}}}
}
// NewPipeline allocates and returns a new empty pipeline. If name is empty, one
// is generated by gstreamer.
func NewPipeline(name string) (*Pipeline, error) {
@@ -30,7 +40,7 @@ func NewPipeline(name string) (*Pipeline, error) {
if pipeline == nil {
return nil, errors.New("Could not create new pipeline")
}
return wrapPipeline(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(pipeline))}), nil
return FromGstPipelineUnsafeNone(unsafe.Pointer(pipeline)), nil
}
// NewPipelineFromString creates a new gstreamer pipeline from the given launch string.
@@ -47,7 +57,7 @@ func NewPipelineFromString(launchv string) (*Pipeline, error) {
errMsg := C.GoString(gerr.message)
return nil, errors.New(errMsg)
}
return wrapPipeline(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(pipeline))}), nil
return FromGstPipelineUnsafeNone(unsafe.Pointer(pipeline)), nil
}
// Instance returns the native GstPipeline instance.
@@ -57,7 +67,7 @@ func (p *Pipeline) Instance() *C.GstPipeline { return C.toGstPipeline(p.Unsafe()
func (p *Pipeline) GetPipelineBus() *Bus {
if p.bus == nil {
cBus := C.gst_pipeline_get_bus((*C.GstPipeline)(p.Instance()))
p.bus = wrapBus(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(cBus))})
p.bus = FromGstBusUnsafeFull(unsafe.Pointer(cBus))
}
return p.bus
}
@@ -65,7 +75,7 @@ func (p *Pipeline) GetPipelineBus() *Bus {
// GetPipelineClock returns the global clock for this pipeline.
func (p *Pipeline) GetPipelineClock() *Clock {
cClock := C.gst_pipeline_get_pipeline_clock((*C.GstPipeline)(p.Instance()))
return wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(cClock))})
return FromGstClockUnsafeFull(unsafe.Pointer(cClock))
}
/*
@@ -92,35 +102,3 @@ func (p *Pipeline) SetAutoFlushBus(b bool) {
func (p *Pipeline) Start() error {
return p.SetState(StatePlaying)
}
// Destroy will attempt to stop the pipeline and then unref once the stream has
// fully completed.
func (p *Pipeline) Destroy() error {
if err := p.BlockSetState(StateNull); err != nil {
return err
}
p.Unref()
return nil
}
// Wait waits for the given pipeline to reach end of stream or be stopped.
func Wait(p *Pipeline) {
if p.Instance() == nil {
return
}
msgCh := p.GetPipelineBus().MessageChan()
for {
select {
default:
if p.Instance() == nil || p.GetState() == StateNull {
return
}
case msg := <-msgCh:
defer msg.Unref()
switch msg.Type() {
case MessageEOS:
return
}
}
}
}

View File

@@ -53,8 +53,8 @@ import (
"errors"
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
gopointer "github.com/mattn/go-pointer"
"github.com/tinyzimmer/go-glib/glib"
)
// PluginMetadata represents the information to include when registering a new plugin
@@ -114,6 +114,16 @@ type PluginInitFunc func(*Plugin) bool
// Plugin is a go representation of a GstPlugin.
type Plugin struct{ *Object }
// FromGstPluginUnsafeNone wraps the given pointer in a Plugin.
func FromGstPluginUnsafeNone(plugin unsafe.Pointer) *Plugin {
return &Plugin{wrapObject(glib.TransferNone(plugin))}
}
// FromGstPluginUnsafeFull wraps the given pointer in a Plugin.
func FromGstPluginUnsafeFull(plugin unsafe.Pointer) *Plugin {
return &Plugin{wrapObject(glib.TransferFull(plugin))}
}
// RegisterPlugin will register a static plugin, i.e. a plugin which is private to an application
// or library and contained within the application or library (as opposed to being shipped as a
// separate module file).
@@ -150,7 +160,7 @@ func LoadPluginByName(name string) *Plugin {
if plugin == nil {
return nil
}
return wrapPlugin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(plugin))})
return FromGstPluginUnsafeFull(unsafe.Pointer(plugin))
}
// LoadPluginFile loads the given plugin and refs it. If an error is returned Plugin will be nil.
@@ -163,7 +173,7 @@ func LoadPluginFile(fpath string) (*Plugin, error) {
defer C.g_free((C.gpointer)(gerr))
return nil, errors.New(C.GoString(gerr.message))
}
return wrapPlugin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(plugin))}), nil
return FromGstPluginUnsafeFull(unsafe.Pointer(plugin)), nil
}
// Instance returns the underlying GstPlugin instance.

View File

@@ -5,8 +5,6 @@ import "C"
import (
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
)
// PluginFeature wraps the C GstPluginFeature.
@@ -21,7 +19,7 @@ func (p *PluginFeature) GetPlugin() *Plugin {
if plugin == nil {
return nil
}
return wrapPlugin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(plugin))})
return FromGstPluginUnsafeFull(unsafe.Pointer(plugin))
}
// GetPluginName returns the name of the plugin that provides this feature.

View File

@@ -3,6 +3,7 @@ package gst
// #include "gst.go.h"
import "C"
import (
"runtime"
"time"
"unsafe"
@@ -17,32 +18,45 @@ type Query struct {
// Type returns the type of the Query.
func (q *Query) Type() QueryType { return QueryType(q.ptr._type) }
// FromGstQueryUnsafe wraps the pointer to the given C GstQuery with the go type.
// FromGstQueryUnsafeNone wraps the pointer to the given C GstQuery with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstQueryUnsafe(query unsafe.Pointer) *Query { return wrapQuery((*C.GstQuery)(query)) }
func FromGstQueryUnsafeNone(query unsafe.Pointer) *Query {
q := wrapQuery((*C.GstQuery)(query))
q.Ref()
runtime.SetFinalizer(q, (*Query).Unref)
return q
}
// FromGstQueryUnsafeFull wraps the pointer to the given C GstQuery with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstQueryUnsafeFull(query unsafe.Pointer) *Query {
q := wrapQuery((*C.GstQuery)(query))
runtime.SetFinalizer(q, (*Query).Unref)
return q
}
// NewAcceptCapsQuery constructs a new query object for querying if caps are accepted.
func NewAcceptCapsQuery(caps *Caps) *Query {
return wrapQuery(C.gst_query_new_accept_caps(caps.Instance()))
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_accept_caps(caps.Instance())))
}
// NewAllocationQuery constructs a new query object for querying the allocation properties.
func NewAllocationQuery(caps *Caps, needPool bool) *Query {
return wrapQuery(C.gst_query_new_allocation(
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_allocation(
caps.Instance(), gboolean(needPool),
))
)))
}
// NewBitrateQuery constructs a new query object for querying the bitrate.
func NewBitrateQuery() *Query {
return wrapQuery(C.gst_query_new_bitrate())
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_bitrate()))
}
// NewBufferingQuery constructs a new query object for querying the buffering status of a stream.
func NewBufferingQuery(format Format) *Query {
return wrapQuery(C.gst_query_new_buffering(
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_buffering(
C.GstFormat(format),
))
)))
}
// NewCapsQuery constructs a new query object for querying the caps.
@@ -59,81 +73,81 @@ func NewBufferingQuery(format Format) *Query {
// The filter is used to restrict the result caps, only the caps matching filter should be returned from the CAPS
// query. Specifying a filter might greatly reduce the amount of processing an element needs to do.
func NewCapsQuery(caps *Caps) *Query {
return wrapQuery(C.gst_query_new_caps(caps.Instance()))
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_caps(caps.Instance())))
}
// NewContextQuery constructs a new query object for querying the pipeline-local context.
func NewContextQuery(ctxType string) *Query {
cName := C.CString(ctxType)
defer C.free(unsafe.Pointer(cName))
return wrapQuery(C.gst_query_new_context(
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_context(
(*C.gchar)(unsafe.Pointer(cName)),
))
)))
}
// NewConvertQuery constructs a new convert query object. A convert query is used to ask for a conversion between one
// format and another.
func NewConvertQuery(srcFormat, destFormat Format, value int64) *Query {
return wrapQuery(C.gst_query_new_convert(
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_convert(
C.GstFormat(srcFormat), C.gint64(value), C.GstFormat(destFormat),
))
)))
}
// NewCustomQuery constructs a new custom query object.
func NewCustomQuery(queryType QueryType, structure *Structure) *Query {
return wrapQuery(C.gst_query_new_custom(
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_custom(
C.GstQueryType(queryType),
structure.Instance(),
))
)))
}
// NewDrainQuery constructs a new query object for querying the drain state.
func NewDrainQuery() *Query {
return wrapQuery(C.gst_query_new_drain())
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_drain()))
}
// NewDurationQuery constructs a new stream duration query object to query in the given format. A duration query will give the
// total length of the stream.
func NewDurationQuery(format Format) *Query {
return wrapQuery(C.gst_query_new_duration(C.GstFormat(format)))
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_duration(C.GstFormat(format))))
}
// NewFormatsQuery constructs a new query object for querying formats of the stream.
func NewFormatsQuery() *Query {
return wrapQuery(C.gst_query_new_formats())
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_formats()))
}
// NewLatencyQuery constructs a new latency query object. A latency query is usually performed by sinks to compensate for additional
// latency introduced by elements in the pipeline.
func NewLatencyQuery() *Query {
return wrapQuery(C.gst_query_new_latency())
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_latency()))
}
// NewPositionQuery constructs a new query stream position query object. A position query is used to query the current position of playback
// in the streams, in some format.
func NewPositionQuery(format Format) *Query {
return wrapQuery(C.gst_query_new_position(C.GstFormat(format)))
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_position(C.GstFormat(format))))
}
// NewSchedulingQuery constructs a new query object for querying the scheduling properties.
func NewSchedulingQuery() *Query {
return wrapQuery(C.gst_query_new_scheduling())
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_scheduling()))
}
// NewSeekingQuery constructs a new query object for querying seeking properties of the stream.
func NewSeekingQuery(format Format) *Query {
return wrapQuery(C.gst_query_new_seeking(C.GstFormat(format)))
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_seeking(C.GstFormat(format))))
}
// NewSegmentQuery constructs a new segment query object. A segment query is used to discover information about the currently configured segment
// for playback.
func NewSegmentQuery(format Format) *Query {
return wrapQuery(C.gst_query_new_segment(C.GstFormat(format)))
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_segment(C.GstFormat(format))))
}
// NewURIQuery constructs a new query URI query object. An URI query is used to query the current URI that is used by the source or sink.
func NewURIQuery() *Query {
return wrapQuery(C.gst_query_new_uri())
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_new_uri()))
}
// Instance returns the underlying GstQuery instance.
@@ -172,7 +186,7 @@ func (q *Query) AddSchedulingMode(mode PadMode) {
// Copy copies the given query using the copy function of the parent GstStructure.
func (q *Query) Copy() *Query {
return wrapQuery(C.gst_query_copy(q.Instance()))
return FromGstQueryUnsafeFull(unsafe.Pointer(C.gst_query_copy(q.Instance())))
}
// FindAllocationMeta checks if query has metadata api set. When this function returns TRUE, index will contain the index where the requested
@@ -230,7 +244,7 @@ func (q *Query) HasSchedulingModeWithFlags(mode PadMode, flags SchedulingFlags)
func (q *Query) ParseAcceptCaps() *Caps {
caps := &C.GstCaps{}
C.gst_query_parse_accept_caps(q.Instance(), &caps)
return wrapCaps(caps)
return FromGstCapsUnsafeNone(unsafe.Pointer(caps))
}
// ParseAcceptCapsResult parses the result from the caps query.
@@ -245,7 +259,7 @@ func (q *Query) ParseAllocation() (caps *Caps, needPool bool) {
gcaps := &C.GstCaps{}
var needz C.gboolean
C.gst_query_parse_allocation(q.Instance(), &gcaps, &needz)
return wrapCaps(gcaps), gobool(needz)
return FromGstCapsUnsafeNone(unsafe.Pointer(gcaps)), gobool(needz)
}
// ParseBitrate gets the results of a bitrate query. See also SetBitrate.
@@ -285,14 +299,14 @@ func (q *Query) ParseBufferingStats() (mode BufferingMode, avgIn, avgOut int, bu
func (q *Query) ParseCaps() *Caps {
caps := &C.GstCaps{}
C.gst_query_parse_caps(q.Instance(), &caps)
return wrapCaps(caps)
return FromGstCapsUnsafeNone(unsafe.Pointer(caps))
}
// ParseCapsResult gets the caps result from query. The caps remains valid as long as query remains valid.
func (q *Query) ParseCapsResult() *Caps {
caps := &C.GstCaps{}
C.gst_query_parse_caps_result(q.Instance(), &caps)
return wrapCaps(caps)
return FromGstCapsUnsafeNone(unsafe.Pointer(caps))
}
// ParseContext gets the context from the context query. The context remains valid as long as query remains valid.
@@ -300,7 +314,7 @@ func (q *Query) ParseContext() *Context {
var _ctx *C.GstContext
ctx := C.makeContextWritable(_ctx)
C.gst_query_parse_context(q.Instance(), &ctx)
return wrapContext(ctx)
return FromGstContextUnsafeNone(unsafe.Pointer(ctx))
}
// ParseContextType parses a context type from an existing GST_QUERY_CONTEXT query.
@@ -357,7 +371,7 @@ func (q *Query) ParseAllocationParamAt(idx uint) (*Allocator, *AllocationParams)
alloc := &C.GstAllocator{}
params := C.GstAllocationParams{}
C.gst_query_parse_nth_allocation_param(q.Instance(), C.guint(idx), &alloc, &params)
return wrapAllocator(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(alloc))}), wrapAllocationParams(&params)
return FromGstAllocatorUnsafeFull(unsafe.Pointer(alloc)), wrapAllocationParams(&params)
}
// ParseAllocationPoolAt gets the pool parameters in query.
@@ -365,7 +379,7 @@ func (q *Query) ParseAllocationPoolAt(idx uint) (pool *BufferPool, size, minBuff
gpool := &C.GstBufferPool{}
var gs, gmin, gmax C.guint
C.gst_query_parse_nth_allocation_pool(q.Instance(), C.guint(idx), &gpool, &gs, &gmin, &gmax)
return wrapBufferPool(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gpool))}), uint(gs), uint(gmin), uint(gmax)
return FromGstBufferPoolUnsafeFull(unsafe.Pointer(gpool)), uint(gs), uint(gmin), uint(gmax)
}
// ParseBufferingRangeAt parses an available query and get the start and stop values stored at the index of the buffered ranges array.

View File

@@ -13,10 +13,20 @@ import (
// Registry is a go representation of a GstRegistry.
type Registry struct{ *Object }
// FromGstRegistryUnsafeNone wraps the given GstRegistry pointer.
func FromGstRegistryUnsafeNone(registry unsafe.Pointer) *Registry {
return &Registry{wrapObject(glib.TransferNone(registry))}
}
// FromGstRegistryUnsafeFull wraps the given GstRegistry pointer.
func FromGstRegistryUnsafeFull(registry unsafe.Pointer) *Registry {
return &Registry{wrapObject(glib.TransferFull(registry))}
}
// GetRegistry returns the default global GstRegistry.
func GetRegistry() *Registry {
registry := C.gst_registry_get()
return wrapRegistry(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(registry))})
return FromGstRegistryUnsafeNone(unsafe.Pointer(registry))
}
// Instance returns the underlying GstRegistry instance.
@@ -30,7 +40,7 @@ func (r *Registry) FindPlugin(name string) (*Plugin, error) {
if plugin == nil {
return nil, fmt.Errorf("No plugin named %s found", name)
}
return wrapPlugin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(plugin))}), nil
return FromGstPluginUnsafeFull(unsafe.Pointer(plugin)), nil
}
// LookupFeature looks up the given plugin feature by name. Unref after usage.
@@ -41,5 +51,5 @@ func (r *Registry) LookupFeature(name string) (*PluginFeature, error) {
if feat == nil {
return nil, fmt.Errorf("No feature named %s found", name)
}
return wrapPluginFeature(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(feat))}), nil
return wrapPluginFeature(glib.TransferFull(unsafe.Pointer(feat))), nil
}

View File

@@ -3,16 +3,32 @@ package gst
// #include "gst.go.h"
import "C"
import "unsafe"
import (
"runtime"
"unsafe"
)
// Sample is a go wrapper around a GstSample object.
type Sample struct {
sample *C.GstSample
}
// FromGstSampleUnsafe wraps the pointer to the given C GstSample with the go type.
// FromGstSampleUnsafeNone wraps the pointer to the given C GstSample with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstSampleUnsafe(sample unsafe.Pointer) *Sample { return wrapSample(C.toGstSample(sample)) }
func FromGstSampleUnsafeNone(sample unsafe.Pointer) *Sample {
s := wrapSample(C.toGstSample(sample))
s.Ref()
runtime.SetFinalizer(s, (*Sample).Unref)
return s
}
// FromGstSampleUnsafeFull wraps the pointer to the given C GstSample with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstSampleUnsafeFull(sample unsafe.Pointer) *Sample {
s := wrapSample(C.toGstSample(sample))
runtime.SetFinalizer(s, (*Sample).Unref)
return s
}
// Instance returns the underlying *GstSample instance.
func (s *Sample) Instance() *C.GstSample { return C.toGstSample(unsafe.Pointer(s.sample)) }
@@ -24,21 +40,25 @@ func (s *Sample) Ref() *Sample {
// Copy creates a copy of the given sample. This will also make a newly allocated copy of the data
// the source sample contains.
func (s *Sample) Copy() *Sample { return wrapSample(C.gst_sample_copy(s.Instance())) }
func (s *Sample) Copy() *Sample {
return FromGstSampleUnsafeFull(unsafe.Pointer(C.gst_sample_copy(s.Instance())))
}
// GetBuffer returns the buffer inside this sample.
func (s *Sample) GetBuffer() *Buffer {
return wrapBuffer(C.gst_sample_get_buffer((*C.GstSample)(s.Instance())))
return FromGstBufferUnsafeNone(unsafe.Pointer(C.gst_sample_get_buffer((*C.GstSample)(s.Instance()))))
}
// GetBufferList gets the buffer list associated with this sample.
func (s *Sample) GetBufferList() *BufferList {
return wrapBufferList(C.gst_sample_get_buffer_list(s.Instance()))
return FromGstBufferListUnsafeNone(unsafe.Pointer(C.gst_sample_get_buffer_list(s.Instance())))
}
// GetCaps returns the caps associated with this sample. Take a ref if you need to hold on to them
// longer then the life of the sample.
func (s *Sample) GetCaps() *Caps { return wrapCaps(C.gst_sample_get_caps(s.Instance())) }
func (s *Sample) GetCaps() *Caps {
return FromGstCapsUnsafeNone(unsafe.Pointer(C.gst_sample_get_caps(s.Instance())))
}
// GetInfo gets extra information about this sample. The structure remains valid as long as sample is valid.
func (s *Sample) GetInfo() *Structure { return wrapStructure(C.gst_sample_get_info(s.Instance())) }

View File

@@ -10,13 +10,12 @@ type Segment struct {
ptr *C.GstSegment
}
// FromGstSegmentUnsafe wraps the given C GstSegment in the go type. It is meant for internal usage
// and exported for visibilty to other packages.
// FromGstSegmentUnsafe wraps the GstSegment pointer.
func FromGstSegmentUnsafe(segment unsafe.Pointer) *Segment {
return wrapSegment((*C.GstSegment)(segment))
}
// NewSegment allocates and initializes a new Segment.
// NewSegment allocates and initializes a new Segment. Free when you are finished.
func NewSegment() *Segment {
return wrapSegment(C.gst_segment_new())
}

View File

@@ -12,12 +12,22 @@ import (
// Stream is a Go representation of a GstStream.
type Stream struct{ *Object }
// FromGstStreamUnsafeNone captures a pointer with a ref and finalizer.
func FromGstStreamUnsafeNone(stream unsafe.Pointer) *Stream {
return &Stream{wrapObject(glib.TransferNone(stream))}
}
// FromGstStreamUnsafeFull captures a pointer with just a finalizer.
func FromGstStreamUnsafeFull(stream unsafe.Pointer) *Stream {
return &Stream{wrapObject(glib.TransferNone(stream))}
}
// NewStream returns a new Stream with the given ID, caps, type, and flags.
func NewStream(id string, caps *Caps, sType StreamType, flags StreamFlags) *Stream {
cID := C.CString(id)
defer C.free(unsafe.Pointer(cID))
stream := C.gst_stream_new(cID, caps.Instance(), C.GstStreamType(sType), C.GstStreamFlags(flags))
return wrapStream(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(stream))})
return FromGstStreamUnsafeFull(unsafe.Pointer(stream))
}
// Instance returns the underlying GstStream.
@@ -27,7 +37,7 @@ func (s *Stream) Instance() *C.GstStream {
// Caps returns the caps for this stream.
func (s *Stream) Caps() *Caps {
return wrapCaps(C.gst_stream_get_caps(s.Instance()))
return FromGstCapsUnsafeFull(unsafe.Pointer(C.gst_stream_get_caps(s.Instance())))
}
// StreamFlags returns the flags for this stream.
@@ -51,7 +61,7 @@ func (s *Stream) Tags() *TagList {
if tags == nil {
return nil
}
return wrapTagList(tags)
return FromGstTagListUnsafeFull(unsafe.Pointer(tags))
}
// SetCaps sets the caps for this stream.

View File

@@ -13,13 +13,23 @@ import (
// StreamCollection is a Go representation of a GstStreamCollection.
type StreamCollection struct{ *Object }
// FromGstStreamCollectionUnsafeNone captures a pointer with a ref and finalizer.
func FromGstStreamCollectionUnsafeNone(stream unsafe.Pointer) *StreamCollection {
return &StreamCollection{wrapObject(glib.TransferNone(stream))}
}
// FromGstStreamCollectionUnsafeFull captures a pointer with just a finalizer.
func FromGstStreamCollectionUnsafeFull(stream unsafe.Pointer) *StreamCollection {
return &StreamCollection{wrapObject(glib.TransferFull(stream))}
}
// NewStreamCollection returns a new StreamCollection with an upstream parent
// of the given stream ID.
func NewStreamCollection(upstreamID string) *StreamCollection {
cID := C.CString(upstreamID)
defer C.free(unsafe.Pointer(cID))
collection := C.gst_stream_collection_new(cID)
return wrapStreamCollection(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(collection))})
return FromGstStreamCollectionUnsafeFull(unsafe.Pointer(collection))
}
// Instance returns the underlying GstStreamCollection.
@@ -43,7 +53,7 @@ func (s *StreamCollection) GetSize() uint {
// GetStreamAt returns the stream at the given index in this collection.
func (s *StreamCollection) GetStreamAt(idx uint) *Stream {
stream := C.gst_stream_collection_get_stream(s.Instance(), C.guint(idx))
return wrapStream(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(stream))})
return FromGstStreamUnsafeNone(unsafe.Pointer(stream))
}
// GetUpstreamID retrieves the upstream ID for this collection.

View File

@@ -4,8 +4,6 @@ package gst
import "C"
import (
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
)
// SystemClock wraps GstSystemClock
@@ -14,6 +12,5 @@ type SystemClock struct{ *Clock }
// ObtainSystemClock returns the default SystemClock. The refcount of the clock will be
// increased so you need to unref the clock after usage.
func ObtainSystemClock() *SystemClock {
clock := C.gst_system_clock_obtain()
return &SystemClock{wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(clock))})}
return &SystemClock{FromGstClockUnsafeFull(unsafe.Pointer(C.gst_system_clock_obtain()))}
}

View File

@@ -14,6 +14,7 @@ void cgoTagForEachFunc (const GstTagList * tagList, const gchar * tag, gpointer
import "C"
import (
"runtime"
"time"
"unsafe"
@@ -27,9 +28,22 @@ type TagList struct {
ptr *C.GstTagList
}
// FromGstTagListUnsafe wraps the pointer to the given C GstTagList with the go type.
// FromGstTagListUnsafeNone wraps the pointer to the given C GstTagList with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstTagListUnsafe(tags unsafe.Pointer) *TagList { return wrapTagList(C.toGstTagList(tags)) }
func FromGstTagListUnsafeNone(tags unsafe.Pointer) *TagList {
tl := wrapTagList(C.toGstTagList(tags))
tl.Ref()
runtime.SetFinalizer(tl, (*TagList).Unref)
return tl
}
// FromGstTagListUnsafeFull wraps the pointer to the given C GstTagList with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstTagListUnsafeFull(tags unsafe.Pointer) *TagList {
tl := wrapTagList(C.toGstTagList(tags))
runtime.SetFinalizer(tl, (*TagList).Unref)
return tl
}
// NewEmptyTagList returns a new empty tag list.
//
@@ -38,7 +52,7 @@ func FromGstTagListUnsafe(tags unsafe.Pointer) *TagList { return wrapTagList(C.t
// // true
//
func NewEmptyTagList() *TagList {
return wrapTagList(C.gst_tag_list_new_empty())
return FromGstTagListUnsafeFull(unsafe.Pointer(C.gst_tag_list_new_empty()))
}
// NewTagListFromString creates a new tag list from the given string. This is the same format produced
@@ -50,7 +64,7 @@ func NewTagListFromString(tags string) *TagList {
if tagList == nil {
return nil
}
return wrapTagList(tagList)
return FromGstTagListUnsafeFull(unsafe.Pointer(tagList))
}
// Instance returns the underlying GstTagList instance.
@@ -105,7 +119,9 @@ func (t *TagList) AddValues(mergeMode TagMergeMode, tag Tag, vals ...interface{}
// to hold on to a reference to the data, you should use Ref.
//
// When you are finished with the taglist, call Unref on it.
func (t *TagList) Copy() *TagList { return wrapTagList(C.gst_tag_list_copy(t.Instance())) }
func (t *TagList) Copy() *TagList {
return FromGstTagListUnsafeFull(unsafe.Pointer(C.gst_tag_list_copy(t.Instance())))
}
// TagListForEachFunc is a function that will be called in ForEach. The function may not modify the tag list.
type TagListForEachFunc func(tagList *TagList, tag Tag)
@@ -387,7 +403,7 @@ func (t *TagList) GetSample(tag Tag) (value *Sample, ok bool) {
&gout,
)
if gobool(gok) {
return wrapSample(gout), true
return FromGstSampleUnsafeFull(unsafe.Pointer(gout)), true
}
return nil, false
}
@@ -405,7 +421,7 @@ func (t *TagList) GetSampleIndex(tag Tag, idx uint) (value *Sample, ok bool) {
&gout,
)
if gobool(gok) {
return wrapSample(gout), true
return FromGstSampleUnsafeFull(unsafe.Pointer(gout)), true
}
return nil, false
}
@@ -539,16 +555,16 @@ func (t *TagList) IsWritable() bool { return gobool(C.tagListIsWritable(t.Instan
// MakeWritable will return a writable copy of the tag list if it is not already so.
func (t *TagList) MakeWritable() *TagList {
return wrapTagList(C.makeTagListWritable(t.Instance()))
return FromGstTagListUnsafeFull(unsafe.Pointer(C.makeTagListWritable(t.Instance())))
}
// Merge merges the two tag lists with the given mode.
func (t *TagList) Merge(tagList *TagList, mergeMode TagMergeMode) *TagList {
return wrapTagList(C.gst_tag_list_merge(
return FromGstTagListUnsafeFull(unsafe.Pointer(C.gst_tag_list_merge(
t.Instance(),
tagList.Instance(),
C.GstTagMergeMode(mergeMode),
))
)))
}
// NumTags returns the number of key/value pairs in ths TagList

View File

@@ -50,7 +50,7 @@ func (t *gstTagSetter) GetTagList() *TagList {
if tagList == nil {
return nil
}
return wrapTagList(tagList)
return FromGstTagListUnsafeNone(unsafe.Pointer(tagList))
}
func (t *gstTagSetter) AddTagValue(mergeMode TagMergeMode, tagKey Tag, tagValue interface{}) {

View File

@@ -2,16 +2,32 @@ package gst
// #include "gst.go.h"
import "C"
import "unsafe"
import (
"runtime"
"unsafe"
)
// TOC is a go representation of a GstToc.
type TOC struct {
ptr *C.GstToc
}
// FromGstTOCUnsafe wraps the pointer to the given C GstToc with the go type.
// FromGstTOCUnsafeNone wraps the pointer to the given C GstToc with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstTOCUnsafe(toc unsafe.Pointer) *TOC { return wrapTOC((*C.GstToc)(toc)) }
func FromGstTOCUnsafeNone(toc unsafe.Pointer) *TOC {
gotoc := wrapTOC((*C.GstToc)(toc))
gotoc.Ref()
runtime.SetFinalizer(gotoc, (*TOC).Unref)
return gotoc
}
// FromGstTOCUnsafeFull wraps the pointer to the given C GstToc with the go type.
// This is meant for internal usage and is exported for visibility to other packages.
func FromGstTOCUnsafeFull(toc unsafe.Pointer) *TOC {
gotoc := wrapTOC((*C.GstToc)(toc))
runtime.SetFinalizer(gotoc, (*TOC).Unref)
return gotoc
}
// NewTOC returns a new TOC with the given scope.
func NewTOC(scope TOCScope) *TOC {
@@ -19,7 +35,7 @@ func NewTOC(scope TOCScope) *TOC {
if toc == nil {
return nil
}
return wrapTOC(toc)
return FromGstTOCUnsafeFull(unsafe.Pointer(toc))
}
// Instance returns the underlying GstToc instance.
@@ -38,12 +54,12 @@ func (t *TOC) Unref() {
// MakeWritable returns a writable copy of the TOC if it isn't already,
func (t *TOC) MakeWritable() *TOC {
return wrapTOC(C.makeTocWritable(t.Instance()))
return FromGstTOCUnsafeFull(unsafe.Pointer(C.makeTocWritable(t.Instance())))
}
// Copy creates a copy of the TOC.
func (t *TOC) Copy() *TOC {
return wrapTOC(C.copyToc(t.Instance()))
return FromGstTOCUnsafeFull(unsafe.Pointer(C.copyToc(t.Instance())))
}
// AppendEntry appends the given TOCEntry to this TOC.
@@ -64,7 +80,7 @@ func (t *TOC) FindEntry(uid string) *TOCEntry {
if entry == nil {
return nil
}
return wrapTOCEntry(entry)
return FromGstTocEntryUnsafeNone(unsafe.Pointer(entry))
}
// GetEntries returns a list of all TOCEntries.
@@ -79,7 +95,7 @@ func (t *TOC) GetEntries() []*TOCEntry {
if entry == nil {
break
}
out = append(out, wrapTOCEntry((*C.GstTocEntry)(unsafe.Pointer(entry))))
out = append(out, FromGstTocEntryUnsafeNone(unsafe.Pointer(entry)))
}
return out
}
@@ -95,7 +111,7 @@ func (t *TOC) GetTags() *TagList {
if tagList == nil {
return nil
}
return wrapTagList(tagList)
return FromGstTagListUnsafeNone(unsafe.Pointer(tagList))
}
// MergeTags merges the given tags into this TOC's TagList.
@@ -105,7 +121,7 @@ func (t *TOC) MergeTags(tagList *TagList, mergeMode TagMergeMode) {
// SetTags sets tags for the entire TOC.
func (t *TOC) SetTags(tagList *TagList) {
C.gst_toc_set_tags(t.Instance(), tagList.Instance())
C.gst_toc_set_tags(t.Instance(), tagList.Ref().Instance())
}
// TOCEntry is a go representation of a GstTocEntry,
@@ -113,6 +129,21 @@ type TOCEntry struct {
ptr *C.GstTocEntry
}
// FromGstTocEntryUnsafeNone wraps the given TOCEntry.
func FromGstTocEntryUnsafeNone(entry unsafe.Pointer) *TOCEntry {
t := wrapTOCEntry((*C.GstTocEntry)(entry))
t.Ref()
runtime.SetFinalizer(t, (*TOCEntry).Unref)
return t
}
// FromGstTocEntryUnsafeFull wraps the given TOCEntry.
func FromGstTocEntryUnsafeFull(entry unsafe.Pointer) *TOCEntry {
t := wrapTOCEntry((*C.GstTocEntry)(entry))
runtime.SetFinalizer(t, (*TOCEntry).Unref)
return t
}
// NewTOCEntry creates a new TOCEntry with the given UID and type.
func NewTOCEntry(entryType TOCEntryType, uid string) *TOCEntry {
cuid := C.CString(uid)
@@ -124,7 +155,7 @@ func NewTOCEntry(entryType TOCEntryType, uid string) *TOCEntry {
if entry == nil {
return nil
}
return wrapTOCEntry(entry)
return FromGstTocEntryUnsafeFull(unsafe.Pointer(entry))
}
// Instance returns the underlying GstTocEntry instance.
@@ -143,17 +174,17 @@ func (t *TOCEntry) Unref() {
// MakeWritable returns a writable copy of the TOCEntry if it is not already so.
func (t *TOCEntry) MakeWritable() *TOCEntry {
return wrapTOCEntry(C.makeTocEntryWritable(t.Instance()))
return FromGstTocEntryUnsafeFull(unsafe.Pointer(C.makeTocEntryWritable(t.Instance())))
}
// Copy creates a copy of the TOCEntry
func (t *TOCEntry) Copy() *TOCEntry {
return wrapTOCEntry(C.copyTocEntry(t.Instance()))
return FromGstTocEntryUnsafeFull(unsafe.Pointer(C.copyTocEntry(t.Instance())))
}
// AppendSubEntry appends the given entry as a subentry to this one.
func (t *TOCEntry) AppendSubEntry(subEntry *TOCEntry) {
C.gst_toc_entry_append_sub_entry(t.Instance(), subEntry.Instance())
C.gst_toc_entry_append_sub_entry(t.Instance(), subEntry.Ref().Instance())
}
// GetEntryType returns the type of this TOCEntry
@@ -180,7 +211,7 @@ func (t *TOCEntry) GetParent() *TOCEntry {
if parent == nil {
return nil
}
return wrapTOCEntry(parent)
return FromGstTocEntryUnsafeNone(unsafe.Pointer(parent))
}
// GetStartStopTimes gets the start and stop times for the TOCEntry if available.
@@ -202,7 +233,7 @@ func (t *TOCEntry) GetSubEntries() []*TOCEntry {
if entry == nil {
break
}
out = append(out, wrapTOCEntry((*C.GstTocEntry)(unsafe.Pointer(entry))))
out = append(out, FromGstTocEntryUnsafeNone(unsafe.Pointer(entry)))
}
return out
}
@@ -213,7 +244,7 @@ func (t *TOCEntry) GetTags() *TagList {
if tagList == nil {
return nil
}
return wrapTagList(tagList)
return FromGstTagListUnsafeNone(unsafe.Pointer(tagList))
}
// GetTOC returns the parent TOC of this entry.
@@ -222,7 +253,7 @@ func (t *TOCEntry) GetTOC() *TOC {
if toc == nil {
return nil
}
return wrapTOC(toc)
return FromGstTOCUnsafeNone(unsafe.Pointer(toc))
}
// GetUID returns the uid of this entry.
@@ -242,6 +273,10 @@ func (t *TOCEntry) IsSequence() bool {
// MergeTags merges the given tags with the given mode.
func (t *TOCEntry) MergeTags(tagList *TagList, mergeMode TagMergeMode) {
if tagList == nil {
C.gst_toc_entry_merge_tags(t.Instance(), nil, C.GstTagMergeMode(mergeMode))
return
}
C.gst_toc_entry_merge_tags(t.Instance(), tagList.Instance(), C.GstTagMergeMode(mergeMode))
}
@@ -257,5 +292,5 @@ func (t *TOCEntry) SetStartStopTimes(startTime, stopTime int64) {
// SetTags sets the tags on the TOC entry.
func (t *TOCEntry) SetTags(tagList *TagList) {
C.gst_toc_entry_set_tags(t.Instance(), tagList.Instance())
C.gst_toc_entry_set_tags(t.Instance(), tagList.Ref().Instance())
}

View File

@@ -2,7 +2,11 @@ package gst
// #include "gst.go.h"
import "C"
import "github.com/tinyzimmer/go-glib/glib"
import (
"unsafe"
"github.com/tinyzimmer/go-glib/glib"
)
// InterfaceTOCSetter represents the GstTocSetter interface GType. Use this when querying bins
// for elements that implement a TOCSetter.
@@ -32,7 +36,7 @@ func (g *gstTOCSetter) GetTOC() *TOC {
if toc == nil {
return nil
}
return wrapTOC(toc)
return FromGstTOCUnsafeFull(unsafe.Pointer(toc))
}
func (g *gstTOCSetter) SetTOC(toc *TOC) { C.gst_toc_setter_set_toc(g.Instance(), toc.Instance()) }

View File

@@ -26,6 +26,8 @@ import (
"github.com/tinyzimmer/go-glib/glib"
)
var globalURIHdlr URIHandler
// InterfaceURIHandler represents the GstURIHandler interface GType. Use this when querying bins
// for elements that implement a URIHandler, or when signaling that a GoObjectSubclass provides this
// interface. Note that the way this interface is implemented, it can only be used once per plugin.
@@ -66,6 +68,9 @@ func (g *gstURIHandler) Instance() *C.GstURIHandler {
// GetURI gets the currently handled URI.
func (g *gstURIHandler) GetURI() string {
ret := C.gst_uri_handler_get_uri(g.Instance())
if ret == nil {
return ""
}
defer C.g_free((C.gpointer)(unsafe.Pointer(ret)))
return C.GoString(ret)
}

View File

@@ -26,7 +26,6 @@ func wrapBus(obj *glib.Object) *Bus { return &Bus{Object:
func wrapCaps(caps *C.GstCaps) *Caps { return &Caps{native: caps} }
func wrapClock(obj *glib.Object) *Clock { return &Clock{wrapObject(obj)} }
func wrapContext(ctx *C.GstContext) *Context { return &Context{ptr: ctx} }
func wrapDevice(obj *glib.Object) *Device { return &Device{wrapObject(obj)} }
func wrapElement(obj *glib.Object) *Element { return &Element{wrapObject(obj)} }
func wrapEvent(ev *C.GstEvent) *Event { return &Event{ptr: ev} }
func wrapGhostPad(obj *glib.Object) *GhostPad { return &GhostPad{wrapProxyPad(obj)} }
@@ -42,7 +41,6 @@ func wrapPluginFeature(obj *glib.Object) *PluginFeature { return &PluginFeatur
func wrapPlugin(obj *glib.Object) *Plugin { return &Plugin{wrapObject(obj)} }
func wrapProxyPad(obj *glib.Object) *ProxyPad { return &ProxyPad{wrapPad(obj)} }
func wrapQuery(query *C.GstQuery) *Query { return &Query{ptr: query} }
func wrapRegistry(obj *glib.Object) *Registry { return &Registry{wrapObject(obj)} }
func wrapSample(sample *C.GstSample) *Sample { return &Sample{sample: sample} }
func wrapSegment(segment *C.GstSegment) *Segment { return &Segment{ptr: segment} }
func wrapStream(obj *glib.Object) *Stream { return &Stream{wrapObject(obj)} }
@@ -62,10 +60,6 @@ func wrapElementFactory(obj *glib.Object) *ElementFactory {
return &ElementFactory{wrapPluginFeature(obj)}
}
func wrapStreamCollection(obj *glib.Object) *StreamCollection {
return &StreamCollection{wrapObject(obj)}
}
func wrapAllocationParams(obj *C.GstAllocationParams) *AllocationParams {
return &AllocationParams{ptr: obj}
}

View File

@@ -1,10 +1,11 @@
package pbutils
// #include <gst/pbutils/pbutils.h>
/*
#include <gst/pbutils/pbutils.h>
*/
import "C"
import (
"runtime"
"time"
"unsafe"
@@ -77,8 +78,8 @@ func toGObject(o unsafe.Pointer) *glib.Object { return &glib.Object{GObject: gli
// Discoverer represents a GstDiscoverer
type Discoverer struct{ *glib.Object }
func wrapDiscoverer(d *C.GstDiscoverer) *Discoverer {
return &Discoverer{toGObject(unsafe.Pointer(d))}
func wrapDiscovererFull(d *C.GstDiscoverer) *Discoverer {
return &Discoverer{glib.TransferFull(unsafe.Pointer(d))}
}
// NewDiscoverer creates a new Discoverer with the provided timeout.
@@ -95,12 +96,12 @@ func NewDiscoverer(timeout time.Duration) (*Discoverer, error) {
if gerr != nil {
return nil, wrapGerr(gerr)
}
return wrapDiscoverer(ret), nil
return wrapDiscovererFull(ret), nil
}
// Instance returns the underlying GstDiscoverer instance.
func (d *Discoverer) Instance() *C.GstDiscoverer {
return (*C.GstDiscoverer)(unsafe.Pointer(d.Native()))
return (*C.GstDiscoverer)(unsafe.Pointer(d.GObject))
}
// DiscoverURI synchronously discovers the given uri.
@@ -112,24 +113,24 @@ func (d *Discoverer) DiscoverURI(uri string) (*DiscovererInfo, error) {
if err != nil {
return nil, wrapGerr(err)
}
return wrapDiscovererInfo(info), nil
return wrapDiscovererInfoFull(info), nil
}
// DiscovererInfo represents a GstDiscovererInfo
type DiscovererInfo struct{ *glib.Object }
func wrapDiscovererInfo(d *C.GstDiscovererInfo) *DiscovererInfo {
return &DiscovererInfo{toGObject(unsafe.Pointer(d))}
func wrapDiscovererInfoFull(d *C.GstDiscovererInfo) *DiscovererInfo {
return &DiscovererInfo{glib.TransferFull(unsafe.Pointer(d))}
}
// Instance returns the underlying GstDiscovererInfo instance.
func (d *DiscovererInfo) Instance() *C.GstDiscovererInfo {
return (*C.GstDiscovererInfo)(unsafe.Pointer(d.Native()))
return (*C.GstDiscovererInfo)(unsafe.Pointer(d.GObject))
}
// Copy creates a copy of this instance.
func (d *DiscovererInfo) Copy() *DiscovererInfo {
return wrapDiscovererInfo(C.gst_discoverer_info_copy(d.Instance()))
return wrapDiscovererInfoFull(C.gst_discoverer_info_copy(d.Instance()))
}
// GetAudioStreams finds all the DiscovererAudioInfo contained in info.
@@ -204,7 +205,7 @@ func (d *DiscovererInfo) GetTags() *gst.TagList {
if tagList == nil {
return nil
}
return gst.FromGstTagListUnsafe(unsafe.Pointer(tagList))
return gst.FromGstTagListUnsafeNone(unsafe.Pointer(tagList))
}
// GetTOC returns the TOC for the URI stream.
@@ -213,7 +214,7 @@ func (d *DiscovererInfo) GetTOC() *gst.TOC {
if toc == nil {
return nil
}
return gst.FromGstTOCUnsafe(unsafe.Pointer(toc))
return gst.FromGstTOCUnsafeNone(unsafe.Pointer(toc))
}
// GetURI returns the URI for this info.
@@ -239,7 +240,7 @@ func wrapDiscovererStreamInfo(d *C.GstDiscovererStreamInfo) *DiscovererStreamInf
// Instance returns the underlying GstDiscovererStreamInfo instance.
func (d *DiscovererStreamInfo) Instance() *C.GstDiscovererStreamInfo {
return (*C.GstDiscovererStreamInfo)(unsafe.Pointer(d.Native()))
return (*C.GstDiscovererStreamInfo)(unsafe.Pointer(d.GObject))
}
// GetCaps returns the caps from the stream info.
@@ -248,7 +249,7 @@ func (d *DiscovererStreamInfo) GetCaps() *gst.Caps {
if caps == nil {
return nil
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// GetStreamID returns the stream ID of this stream.
@@ -267,7 +268,7 @@ func (d *DiscovererStreamInfo) GetTags() *gst.TagList {
if tagList == nil {
return nil
}
return gst.FromGstTagListUnsafe(unsafe.Pointer(tagList))
return gst.FromGstTagListUnsafeNone(unsafe.Pointer(tagList))
}
// GetTOC gets the TOC contained in this stream
@@ -276,7 +277,7 @@ func (d *DiscovererStreamInfo) GetTOC() *gst.TOC {
if toc == nil {
return nil
}
return gst.FromGstTOCUnsafe(unsafe.Pointer(toc))
return gst.FromGstTOCUnsafeNone(unsafe.Pointer(toc))
}
// DiscovererAudioInfo contains info specific to audio streams.
@@ -284,7 +285,7 @@ type DiscovererAudioInfo struct{ *DiscovererStreamInfo }
// Instance returns the underlying GstDiscovererAudioInfo instance.
func (d *DiscovererAudioInfo) Instance() *C.GstDiscovererAudioInfo {
return (*C.GstDiscovererAudioInfo)(unsafe.Pointer(d.Native()))
return (*C.GstDiscovererAudioInfo)(unsafe.Pointer(d.GObject))
}
// GetBitate returns the bitrate for the audio stream.
@@ -331,7 +332,7 @@ type DiscovererVideoInfo struct{ *DiscovererStreamInfo }
// Instance returns the underlying GstDiscovererVideoInfo instance.
func (d *DiscovererVideoInfo) Instance() *C.GstDiscovererVideoInfo {
return (*C.GstDiscovererVideoInfo)(unsafe.Pointer(d.Native()))
return (*C.GstDiscovererVideoInfo)(unsafe.Pointer(d.GObject))
}
// GetBitrate returns the average or nominal bitrate of the video stream in bits/second.
@@ -394,7 +395,7 @@ type DiscovererContainerInfo struct{ *DiscovererStreamInfo }
// Instance returns the underlying GstDiscovererContainerInfo instance.
func (d *DiscovererContainerInfo) Instance() *C.GstDiscovererContainerInfo {
return (*C.GstDiscovererContainerInfo)(unsafe.Pointer(d.Native()))
return (*C.GstDiscovererContainerInfo)(unsafe.Pointer(d.GObject))
}
// GetStreams returns the list of streams inside this container.
@@ -411,7 +412,7 @@ type DiscovererSubtitleInfo struct{ *DiscovererStreamInfo }
// Instance returns the underlying GstDiscovererSubtitleInfo instance.
func (d *DiscovererSubtitleInfo) Instance() *C.GstDiscovererSubtitleInfo {
return (*C.GstDiscovererSubtitleInfo)(unsafe.Pointer(d.Native()))
return (*C.GstDiscovererSubtitleInfo)(unsafe.Pointer(d.GObject))
}
// GetLanguage returns the language of the subtitles.
@@ -424,57 +425,72 @@ func (d *DiscovererSubtitleInfo) GetLanguage() string {
}
func glistToStreamInfoSlice(glist *C.GList) []*DiscovererStreamInfo {
l := glib.WrapList(uintptr(unsafe.Pointer(&glist)))
out := make([]*DiscovererStreamInfo, 0)
runtime.SetFinalizer(&out, func(_ *[]*DiscovererStreamInfo) { C.gst_discoverer_stream_info_list_free(glist) })
l.Foreach(func(item interface{}) {
st := item.(unsafe.Pointer)
out = append(out, &DiscovererStreamInfo{toGObject(st)})
})
defer C.gst_discoverer_stream_info_list_free(glist)
l := C.g_list_length(glist)
out := make([]*DiscovererStreamInfo, int(l))
for i := 0; i < int(l); i++ {
data := C.g_list_nth_data(glist, C.guint(i))
if data == nil {
return out // safety
}
out[i] = &DiscovererStreamInfo{glib.TransferFull(unsafe.Pointer(data))}
}
return out
}
func glistToAudioInfoSlice(glist *C.GList) []*DiscovererAudioInfo {
l := glib.WrapList(uintptr(unsafe.Pointer(&glist)))
out := make([]*DiscovererAudioInfo, 0)
runtime.SetFinalizer(&out, func(_ *[]*DiscovererAudioInfo) { C.gst_discoverer_stream_info_list_free(glist) })
l.Foreach(func(item interface{}) {
st := item.(unsafe.Pointer)
out = append(out, &DiscovererAudioInfo{&DiscovererStreamInfo{toGObject(st)}})
})
defer C.gst_discoverer_stream_info_list_free(glist)
l := C.g_list_length(glist)
out := make([]*DiscovererAudioInfo, int(l))
for i := 0; i < int(l); i++ {
data := C.g_list_nth_data(glist, C.guint(i))
if data == nil {
return out // safety
}
out[i] = &DiscovererAudioInfo{&DiscovererStreamInfo{glib.TransferFull(unsafe.Pointer(data))}}
}
return out
}
func glistToVideoInfoSlice(glist *C.GList) []*DiscovererVideoInfo {
l := glib.WrapList(uintptr(unsafe.Pointer(&glist)))
defer C.gst_discoverer_stream_info_list_free(glist)
l := C.g_list_length(glist)
out := make([]*DiscovererVideoInfo, 0)
runtime.SetFinalizer(&out, func(_ *[]*DiscovererVideoInfo) { C.gst_discoverer_stream_info_list_free(glist) })
l.Foreach(func(item interface{}) {
st := item.(unsafe.Pointer)
out = append(out, &DiscovererVideoInfo{&DiscovererStreamInfo{toGObject(st)}})
})
for i := 0; i < int(l); i++ {
data := C.g_list_nth_data(glist, C.guint(i))
if data == nil {
return out // safety
}
out[i] = &DiscovererVideoInfo{&DiscovererStreamInfo{glib.TransferFull(unsafe.Pointer(data))}}
}
return out
}
func glistToContainerInfoSlice(glist *C.GList) []*DiscovererContainerInfo {
l := glib.WrapList(uintptr(unsafe.Pointer(&glist)))
defer C.gst_discoverer_stream_info_list_free(glist)
l := C.g_list_length(glist)
out := make([]*DiscovererContainerInfo, 0)
runtime.SetFinalizer(&out, func(_ *[]*DiscovererContainerInfo) { C.gst_discoverer_stream_info_list_free(glist) })
l.Foreach(func(item interface{}) {
st := item.(unsafe.Pointer)
out = append(out, &DiscovererContainerInfo{&DiscovererStreamInfo{toGObject(st)}})
})
for i := 0; i < int(l); i++ {
data := C.g_list_nth_data(glist, C.guint(i))
if data == nil {
return out // safety
}
out[i] = &DiscovererContainerInfo{&DiscovererStreamInfo{glib.TransferFull(unsafe.Pointer(data))}}
}
return out
}
func glistToSubtitleInfoSlice(glist *C.GList) []*DiscovererSubtitleInfo {
l := glib.WrapList(uintptr(unsafe.Pointer(&glist)))
defer C.gst_discoverer_stream_info_list_free(glist)
l := C.g_list_length(glist)
out := make([]*DiscovererSubtitleInfo, 0)
runtime.SetFinalizer(&out, func(_ *[]*DiscovererSubtitleInfo) { C.gst_discoverer_stream_info_list_free(glist) })
l.Foreach(func(item interface{}) {
st := item.(unsafe.Pointer)
out = append(out, &DiscovererSubtitleInfo{&DiscovererStreamInfo{toGObject(st)}})
})
for i := 0; i < int(l); i++ {
data := C.g_list_nth_data(glist, C.guint(i))
if data == nil {
return out // safety
}
out[i] = &DiscovererSubtitleInfo{&DiscovererStreamInfo{glib.TransferFull(unsafe.Pointer(data))}}
}
return out
}

View File

@@ -1,3 +0,0 @@
package gst
var globalURIHdlr URIHandler

View File

@@ -24,9 +24,8 @@ func goVideoConvertSampleCb(gsample *C.GstSample, gerr *C.GError, userData C.gpo
if gerr != nil {
err = wrapGerr(gerr)
}
if sample != nil {
sample = gst.FromGstSampleUnsafe(unsafe.Pointer(sample))
defer sample.Unref()
if gsample != nil {
sample = gst.FromGstSampleUnsafeFull(unsafe.Pointer(gsample))
}
iface := gopointer.Restore(unsafe.Pointer(userData))
if iface == nil {

View File

@@ -49,7 +49,7 @@ func ConvertSample(sample *gst.Sample, toCaps *gst.Caps, timeout time.Duration)
if ret == nil {
return nil, nil
}
return gst.FromGstSampleUnsafe(unsafe.Pointer(ret)), nil
return gst.FromGstSampleUnsafeFull(unsafe.Pointer(ret)), nil
}
// ConvertSampleAsync converts a raw video buffer into the specified output caps.

View File

@@ -271,7 +271,7 @@ func MakeRawCaps(formats []Format) *gst.Caps {
C.guint(len(formats)),
)
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// MakeRawCapsWithFeatures returns a generic raw video caps for formats defined in formats with features. If formats is
@@ -287,7 +287,7 @@ func MakeRawCapsWithFeatures(formats []Format, features *gst.CapsFeatures) *gst.
fromCoreCapsFeatures(features),
)
}
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}
// Info returns the FormatInfo for this video format.

View File

@@ -35,6 +35,7 @@ gint infoWidth (GstVideoInfo * info)
*/
import "C"
import (
"runtime"
"unsafe"
"github.com/tinyzimmer/go-gst/gst"
@@ -163,9 +164,11 @@ type Info struct {
func wrapInfo(vinfo *C.GstVideoInfo) *Info {
info := &Info{vinfo}
runtime.SetFinalizer(info, (*Info).Free)
return info
}
// Free will free this video info
func (i *Info) Free() {
C.gst_video_info_free(i.instance())
}
@@ -384,5 +387,5 @@ func (i *Info) WithPAR(f gst.GFraction) *Info {
// ToCaps returns the caps representation of this video info.
func (i *Info) ToCaps() *gst.Caps {
caps := C.gst_video_info_to_caps(i.instance())
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
return gst.FromGstCapsUnsafeFull(unsafe.Pointer(caps))
}