Giter Site home page Giter Site logo

go-gst's Introduction

banner

go-gst: Go bindings for the GStreamer C libraries

godoc reference GoReportCard

See pkg.go.dev references for documentation and examples.

Please make sure that you have followed the official gstreamer installation instructions before attempting to use the bindings or file an issue.

Requirements

For building applications with this library you need the following:

  • cgo: You must set CGO_ENABLED=1 in your environment when building.
  • gcc and pkg-config
  • GStreamer development files (the method for obtaining these will differ depending on your OS)
    • The core gst package utilizes GStreamer core
    • Subpackages (e.g. app, video) will require development files from their corresponding GStreamer packages
      • Look at pkg_config.go in the imported package to see which C libraries are needed.

Windows

(also see #64)

Compiling on Windows may require some more dancing around than on macOS or Linux. First, make sure you have mingw and pkgconfig installed (links are for the Chocolatey packages). Next, go to the GStreamer downloads page and download the latest "development installer" for your MinGW architecture. When running your applications on another Windows system, they will need to have the "runtime" installed as well.

Finally, to compile the application you'll have to manually set your PKG_CONFIG_PATH to where you installed the GStreamer development files. For example, if you installed GStreamer to C:\gstreamer:

PS> $env:PKG_CONFIG_PATH='C:\gstreamer\1.0\mingw_x86_64\lib\pkgconfig'
PS> go build .

For more information, take a look at this comment with a good run down of the process from compilation to execution.

Quickstart

For more examples see the examples folder here.

// This is the same as the `launch` example. See the godoc and other examples for more 
// in-depth usage of the bindings.
package main

import (
    "fmt"
    "os"
    "strings"

    "github.com/go-gst/go-glib/glib"
    "github.com/go-gst/go-gst/gst"
)

func main() {
    // This example expects a simple `gst-launch-1.0` string as arguments
    if len(os.Args) == 1 {
        fmt.Println("Pipeline string cannot be empty")
        os.Exit(1)
    }

    // Initialize GStreamer with the arguments passed to the program. Gstreamer
    // and the bindings will automatically pop off any handled arguments leaving
    // nothing but a pipeline string (unless other invalid args are present).
    gst.Init(&os.Args)

    // 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)

    // Build a pipeline string from the cli arguments
    pipelineString := strings.Join(os.Args[1:], " ")

    /// Let GStreamer create a pipeline from the parsed launch syntax on the cli.
    pipeline, err := gst.NewPipelineFromString(pipelineString)
    if err != nil {
        fmt.Println(err)
        os.Exit(2)
    }

    // Add a message handler to the pipeline bus, printing interesting information to the console.
    pipeline.GetPipelineBus().AddWatch(func(msg *gst.Message) bool {
        switch msg.Type() {
        case gst.MessageEOS: // When end-of-stream is received flush the pipeling and stop the main loop
            pipeline.BlockSetState(gst.StateNull)
            mainLoop.Quit()
        case gst.MessageError: // Error messages are always fatal
            err := msg.ParseError()
            fmt.Println("ERROR:", err.Error())
            if debug := err.DebugString(); debug != "" {
                fmt.Println("DEBUG:", debug)
            }
            mainLoop.Quit()
        default:
            // All messages implement a Stringer. However, this is
            // typically an expensive thing to do and should be avoided.
            fmt.Println(msg)
        }
        return true
    })

    // Start the pipeline
    pipeline.SetState(gst.StatePlaying)

    // Block and iterate on the main loop
    mainLoop.Run()
}

Contributing

If you find any issues with the bindings or spot areas where things can be improved, feel free to open a PR or start an Issue. Here are a couple of the things on my radar already that I'd be happy to accept help with:

  • Compilation times are insanely slow when working within the bindings. This could be alleviated by further separating aspects of Gstreamer core into their own packages, or removing bindings that would see no use in Go.

  • There are a lot of quirks that make generators difficult to deal with for these bindings. That being said, I'd still like to find a way to start migrating some of them into generated code.

  • The bindings are not structured in a way to make version matching with GStreamer easy. Basically, you need a version compatible with what the bindings were written with (>=1.16).

  • More examples would be nice.

  • Support for writing GStreamer plugins via the bindings is still a work-in-progress. At the very least I need to write more plugings to find more holes.

    • SWIG could be used to fix the need for global interfaces to be matched to C callbacks (most notably the URIHandler currently). The limitation present at the moment is URIHandlers can only be implemented ONCE per plugin.

go-gst's People

Contributors

abrbird avatar atishnazir avatar biglittlebigben avatar brucekim avatar danjenkins avatar frostbyte73 avatar jwmwalrus avatar metal3d avatar nassah221 avatar nielsavonds avatar robmcq avatar rswilli avatar solganik avatar thehamsta avatar tinyzimmer avatar vshashi01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

go-gst's Issues

Figure out what's wrong with windows mingw 12

Github's runner image for windows now uses mingw 12... which causes us errors.

Look at #46 for more information.

Currently we're downgrading to mingw 11 but this action takes 12 minutes and isn't a cache-able thing...

Figure out what's up with using a later version of gcc/mingw on windows

proxysink/proxysrc usage

Hey there, I'm trying to use the proxysink and proxysrc elements. Reading the C example, it looks like this should work (I've seen a similar python example as well)

	sp := p.sourceStr + " ! proxysink name=psink"
	p.logger.Info("source pipe description ", sp)
	sourcePipe, sourceErr := gst.NewPipelineFromString(sp)
	if sourceErr != nil {
		p.logger.WithError(sourceErr).Error("source error")
		return nil, sourceErr
	}
	psink, _ := sourcePipe.GetElementByName("psink")

       //  p.pSrc is pipe2.GetElementByName("psrc")

	setErr := p.pSrc.SetProperty("proxysink", psink)
	if setErr != nil {
		p.logger.WithError(setErr).Fatal("failed setting property")
		return nil, setErr
	}

but this crashes:

panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 15 [running]:
github.com/go-gst/go-glib/glib.(*Value).SetPointer.func1(0x140000126d0, 0x140000126c8)
        /Users/<snip>/vendor/github.com/go-gst/go-glib/glib/gvalue.go:557 +0x44
github.com/go-gst/go-glib/glib.(*Value).SetPointer(0x140000126d0, 0x140000126c8)
        /Users/<snip>/vendor/github.com/go-gst/go-glib/glib/gvalue.go:557 +0x24
github.com/go-gst/go-glib/glib.gValue({0x102fad240, 0x140000126c8})
        /Users/<snip>/vendor/github.com/go-gst/go-glib/glib/gvalue.go:284 +0x1194
github.com/go-gst/go-glib/glib.(*Object).SetProperty(0x140000125f0, {0x102d2f9b5, 0x9}, {0x102fad240, 0x140000126c8})
        /Users/<snip>/vendor/github.com/go-gst/go-glib/glib/gobject.go:215 +0xdc
gitlab.ocado.tech/advanced-technology/production/webcam_pipeline/gstreamer_pipeline.(*gstPipeline).createSource(0x14000116500)
        /Users/<snip>/gstreamer_pipeline/gst.go:166 +0x2c4
.....
Exiting.

after some fiddling, I got it to work with this workaround and the pipelines play correctly

	sp := p.sourceStr + " ! proxysink name=psink"
	p.logger.Info("source pipe description ", sp)
	sourcePipe, sourceErr := gst.NewPipelineFromString(sp)
	if sourceErr != nil {
		p.logger.WithError(sourceErr).Error("source error")
		return nil, sourceErr
	}
	psink, _ := sourcePipe.GetElementByName("psink")

	proxySink := psink.GObject()
       //  p.pSrc is pipe2.GetElementByName("psrc")
	propertyType, _ := p.pSrc.GetPropertyType("proxysink")

	val, typeErr := glib.ValueInit(propertyType)
	if typeErr != nil {
		p.logger.WithError(typeErr).Fatal("whew")
		return nil, typeErr
	}

	val.SetInstance(proxySink.Native())
	setErr := p.pSrc.SetPropertyValue("proxysink", val)
	if setErr != nil {
		p.logger.WithError(setErr).Fatal("failed setting property")
		return nil, setErr
	}

Doing that works, but if I stop (set the state to NULL) the initial pipeline (the one with proxysink) and call Clear on it (which I need to do to handle camera malfunctions) and it goes out of scope in go I get this warning

(<unknown>:70460): GLib-GObject-CRITICAL **: 21:56:01.223: g_object_unref: assertion 'G_IS_OBJECT (object)' failed

which sometimes panics the program

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x2 addr=0xafd4e8709de77de3 pc=0x105a3ba14]

runtime stack:
runtime.throw({0x104eda852?, 0x105146780?})
        /opt/homebrew/opt/go/libexec/src/runtime/panic.go:1047 +0x40 fp=0x16f8dae50 sp=0x16f8dae20 pc=0x1045af9c0
runtime.sigpanic()
        /opt/homebrew/opt/go/libexec/src/runtime/signal_unix.go:825 +0x20c fp=0x16f8dae80 sp=0x16f8dae50 pc=0x1045c67dc

goroutine 3 [syscall]:
runtime.cgocall(0x104e816e0, 0x1400007bd08)
        /opt/homebrew/opt/go/libexec/src/runtime/cgocall.go:157 +0x54 fp=0x1400007bcd0 sp=0x1400007bc90 pc=0x10457b294
github.com/go-gst/go-glib/glib._Cfunc_g_object_unref(0x14e6b5590)
        _cgo_gotypes.go:3588 +0x34 fp=0x1400007bd00 sp=0x1400007bcd0 pc=0x104c69824
github.com/go-gst/go-glib/glib.(*Object).Unref.func1(0x140003a40c8)
        /Users/<snip>/vendor/github.com/go-gst/go-glib/glib/gobject.go:141 +0x4c fp=0x1400007bd40 sp=0x1400007bd00 pc=0x104c7649c
github.com/go-gst/go-glib/glib.(*Object).Unref(0x140003a40c8)
        /Users/<snip>/vendor/github.com/go-gst/go-glib/glib/gobject.go:141 +0x20 fp=0x1400007bd60 sp=0x1400007bd40 pc=0x104c76430
runtime.call16(0x0, 0x105146630, 0x14000122060, 0x10, 0x10, 0x10, 0x1400007be40)
        /opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:478 +0x78 fp=0x1400007bd80 sp=0x1400007bd60 pc=0x1045e1988
runtime.runfinq()
        /opt/homebrew/opt/go/libexec/src/runtime/mfinal.go:255 +0x3d8 fp=0x1400007bfd0 sp=0x1400007bd80 pc=0x104590548
runtime.goexit()
        /opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:1172 +0x4 fp=0x1400007bfd0 sp=0x1400007bfd0 pc=0x1045e3a74
created by runtime.createfing
        /opt/homebrew/opt/go/libexec/src/runtime/mfinal.go:163 +0x4c

Any ideas if I'm doing something wrong? cheers

C compiler warns "Wformat-security"

Every time I start up using this module I get given this output

# github.com/go-gst/go-gst/gst
../../gst/gst_debug.go:14:63: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
../../gst/gst_debug.go:14:63: note: treat the string as an argument to avoid this

Let's see if we can get rid of them

video display support on MacOS

Hello,

I've tried to use autovideosink, glimagesink and osxvideosink with go-gst but I don't see a video window anywhere. If I use gst-launch-1.0, all sinks work fine.

Is this expected?

Audio problem originating from package name for Example

Example in question: https://github.com/go-gst/go-gst/blob/main/examples/decodebin/main.go

If you change the package to not be main, then the audio demo stops working.
The code itself does not give any errors and seems to run, but gstreamer none the less does not output any audio.

Reproduction steps:

  1. Start a new project with the example as your main.go
  2. replace
func main() {
	flag.StringVar(&srcFile, "f", "", "The file to decode")
	flag.Parse()
	if srcFile == "" {
		flag.Usage()
		os.Exit(1)
	}
	examples.RunLoop(func(loop *glib.MainLoop) error {
		pipeline, err := buildPipeline()
		if err != nil {
			return err
		}
		return runPipeline(loop, pipeline)
	})
}

with

func PlayFile(file string) {
        srcFile = file
	examples.RunLoop(func(loop *glib.MainLoop) error {
		pipeline, err := buildPipeline()
		if err != nil {
			return err
		}
		return runPipeline(loop, pipeline)
	})
}
  1. from a new main.go call PlayFile

My Device

  • Fedora
  • X11
  • Pipewire
  • go1.21.6 linux/amd6

Running examples on macos leads to fail

Trying to run the examples on macos leads to:

../../gst/constants.go:42:31: cannot use (_Ciconst_GST_CLOCK_TIME_NONE) (untyped int constant -1) as ClockTime value in variable declaration (overflows)

How to set GstElement *(or *gst.Element) to a Property?

It looks like cgocheck may not be the only headache?

Hi, I'm trying to utilize the "splitmuxsink" to split a streaming(which may have different format), hence need to set different muxer and an appSink elements to the "splitmuxsink". Right now failed to do so.

To show the problem clearly, I picked some relevant codes into a snippet as below:

package main

import (
	"fmt"

	"github.com/go-gst/go-gst/gst"
)

func gstTest() {
	gst.Init(nil)

	var sink *gst.Element
	var err error
	if sink, err = gst.NewElement("splitmuxsink"); err != nil {
		fmt.Println("failed to create splitmuxsink: ", err)
		return
	}

	if err = sink.SetProperty("async-finalize", false); err != nil {
		fmt.Println("failed to set async-finalize to splitmuxsink: ", err)
		return
	}

	var mux *gst.Element
	if mux, err = gst.NewElement("webmmux"); err != nil {
		fmt.Println("failed to create webmmux: ", err)
		return
	}

	if err = sink.SetProperty("muxer", mux); err != nil {
		fmt.Println("failed to set muxer to splitmuxsink: ", err)
		return
	}

	/*
	       var appSink *app.Sink

	   	if appSink, err = app.NewAppSink(); err != nil {
	   		fmt.Println("failed to create appSink: ", err)
	   		return
	   	}	   	
	        if err = sink.SetProperty("sink", appSink); err != nil {
		        fmt.Println("failed to set sink to splitmuxsink: ", err)
		        return
	        }
	*/
}

Running the above codes will get error as "panic: runtime error: cgo argument has Go pointer to unpinned Go pointer", while It seems that glib/gvalue.go already convert the go pointer to a unsafe.Pointer.
Running it with GODEBUG=cgocheck=0 will get error returned by SetProperty(), "Invalid type gpointer for property muxer", which means gst.Element isn't equal to GstElement?

I see in github nobody sets property of a GstElement with golang at all. So wondering how to do that?

Thanks in advance!

SEGFAULT using glib.Value

When setting a property on a custom bin I sometimes get a SIGSEGV.

The error in the stack trace is reported to be at https://github.com/go-gst/go-glib/blob/main/glib/gvalue.go#L52 in the called C function in https://github.com/go-gst/go-glib/blob/b2d34240bcb44a1b341b2f094eb2ab33e1a2aa98/glib/glib.go.h#L126-L128

I will investigate and provide further details.

Currently I suspect that the reason is the conversion from C to golang, and if timed correctly it may interfere with some GC magic.

Small memory leak over time

The application I am writing has the following pprof inuse_objects after some ~20h runtime:

profile002

I am dynamically adding and removing pipeline elements, so it makes sense that there are a lot of elements over the course of this time span, although they should've been cleaned up when not used anymore. The function that creates the elements is the following:

type playbackSource struct {
	bin *gst.Bin

	// the elements in the source, needed so that we do not unref them:
	src,
	decode,
	fader,
	ac1,
	pitch,
	ac2,
	resampler,
	queue *gst.Element

	handle glib.SignalHandle

	settings playbackSettings

	controlSource *gst.InterpolationControlSource
}

// construct a filesrc -> decodebin -> volume -> audioconvert -> pitch -> audioconvert -> resampler -> queue -> <ghost pad> Bin
func newLocalSource(srcLoc string) (*playbackSource, error) {

	xmixLogger.Logger.Infof("creating new playback element")

	currentId := atomic.AddUint64(&id, 1)

	bin := gst.NewBin(fmt.Sprintf("playback%d", currentId))

	src, err := gst.NewElementWithProperties("filesrc", map[string]interface{}{
		"location": srcLoc,
	})

	if err != nil {
		return nil, err
	}

	decode, err := gst.NewElement("decodebin")

	if err != nil {
		return nil, err
	}

	fader, err := gst.NewElementWithName("volume", fmt.Sprintf("fader%d", currentId))

	if err != nil {
		return nil, err
	}

	ac1, err := gst.NewElement("audioconvert")

	if err != nil {
		return nil, err
	}

	pitch, err := gst.NewElement("pitch")

	if err != nil {
		return nil, err
	}

	ac2, err := gst.NewElement("audioconvert")

	if err != nil {
		return nil, err
	}

	resampler, err := gst.NewElement("audioresample")

	if err != nil {
		return nil, err
	}

	queue, err := gst.NewElement("queue")

	if err != nil {
		return nil, err
	}

	err = bin.AddMany(
		src,
		decode,
		fader,
		ac1,
		pitch,
		ac2,
		resampler,
		queue,
	)

	if err != nil {
		return nil, err
	}

	handle, err := decode.Connect("pad-added", func(e *gst.Element, p *gst.Pad) {
		err := e.Link(fader)

		if err != nil {
			panic(fmt.Sprintf("got error during linking: %v", err))
		}
	})

	if err != nil {
		return nil, err
	}

	err = src.Link(decode)

	if err != nil {
		return nil, err
	}

	err = gst.ElementLinkMany(fader, ac1, pitch, ac2, resampler, queue)

	if err != nil {
		return nil, err
	}

	queuePad := queue.GetStaticPad("src")

	ghostPad := gst.NewGhostPad("src", queuePad)

	if !bin.AddPad(ghostPad.Pad) {
		return nil, errors.New("could not add ghostpad to bin")
	}

	csource := gst.NewInterpolationControlSource()
	csource.SetInterpolationMode(gst.InterpolationModeLinear) // maybe we need to change this?
	binding := gst.NewDirectControlBinding(fader.Object, "volume", csource)
	fader.AddControlBinding(&binding.ControlBinding)

	return &playbackSource{
		bin: bin,

		src:       src,
		decode:    decode,
		fader:     fader,
		ac1:       ac1,
		pitch:     pitch,
		ac2:       ac2,
		queue:     queue,
		resampler: resampler,

		handle: handle,

		controlSource: csource,
	}, nil
}

Currently I fear that the connected pad-added signal holds a reference to the elements in the pipeline, so that the go GC doesn't clean them up. The code in question is the following:

        // this function has a reference to the elements above, which means the GO GC wont clean them up
	// which means a memory leak in the C part. Remove this handle when the playout is done to not leak memeory!
	//
	// we cannot remove it after the initial call since a pipeline restart requires that this fires again
	handle, err := decode.Connect("pad-added", func(e *gst.Element, p *gst.Pad) {
		err := e.Link(fader)

		if err != nil {
			panic(fmt.Sprintf("got error during linking: %v", err))
		}
	})

I was trying to investigate the way the signals work in the bindings, but I got lost deep in the cgo calls around here and here


My 2 cents: if "for whatever reason" the function of the pad callback stays in scope, the GC wont clean up the elements. I tried manually disconnecting using the following but this didn't help:

func (p *playbackSource) cleanup() {
	p.decode.HandlerDisconnect(p.handle)
}

gtk4 integration

I am trying to make an customized video player using this project with gotk4 , I could not make it work , tried gotk4-gstreamer as well , still no avail .

Could you give me some directions and guidelines on this , I want to use this project to process rtsp streams and output gtk4paintablesinks , then feed it to gotk4 for final UI customization . Here is a discussion as well .

Or do you happen to know any golang GUI toolkit could fit my purpose better or easier ?

Thank you .

How to write bindings documentation needed

if we ever want to have more contributors, a small documentation would be needed:

e.g.:

  • when to use glib.TransferNone and when to use glib.TransferFull
  • when freeing the params is needed and when it is not
  • general "How to use pkgconfig for golang devs" maybe

this documentation doesn't need to be very long, but would quickstart a new developer that needs some existing functionality from gstreamer

Handling SIGSEGV when in docker container

Related: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3052

The linked issue contains a segmentation fault in gstreamer. It can always happen that gstreamer has some bugs, but in this case it looks like the go runtime handles the signal and discards it. That way the pipeline gets deadlocked.

Thread 20 (LWP 954686 "audiomixer0:src"):
#0  runtime.usleep () at /usr/lib/go/src/runtime/sys_linux_amd64.s:135
#1  0x0000000000473374 in runtime.raisebadsignal (sig=11, c=0xc0006b3310) at /usr/lib/go/src/runtime/signal_unix.go:972
#2  0x00000000004737a7 in runtime.badsignal (sig=11, c=0xc0006b3310) at /usr/lib/go/src/runtime/signal_unix.go:1076
#3  0x00000000004720e8 in runtime.sigtrampgo (sig=11, info=0xc0006b34b0, ctx=0xc0006b3380) at /usr/lib/go/src/runtime/signal_unix.go:468
#4  0x0000000000493cc6 in runtime.sigtramp () at /usr/lib/go/src/runtime/sys_linux_amd64.s:352
#5  <signal handler called>
#6  gst_audio_aggregator_aggregate (agg=0x7f5a8c007ea0, timeout=0) at ../gstreamer/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioaggregator.c:2475
#7  0x00007f5af84d7c6a in gst_aggregator_aggregate_func (self=0x7f5a8c007ea0) at ../gstreamer/subprojects/gstreamer/libs/gst/base/gstaggregator.c:1431
#8  0x00007f5af8d54283 in gst_task_func (task=0x7f5a50024900) at ../gstreamer/subprojects/gstreamer/gst/gsttask.c:384
#9  0x00007f5af8b74483 in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/glib/gthreadpool.c:350
#10 0x00007f5af8b719a5 in g_thread_proxy (data=0x7f5a80001160) at ../glib/glib/gthread.c:831
#11 0x00007f5af879c9eb in start_thread (arg=<optimized out>) at pthread_create.c:444
#12 0x00007f5af8820654 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100

This is not a cgo call, where golang will handle the signal and raise a panic, but instead a signal in a background thread created by gstreamer as a result of a cgo call.

Should we add some code to gst init that listens to SIGSEGV and panics? Should we add a helper method that does that and leave the handling to the user? Is such a signal handler even effective?

It could look something like this:

func CatchGstreamerSegfaults() {
	c := make(chan os.Signal, 1)

	signal.Notify(c, syscall.SIGSEGV)

	<-c

	panic("received segfault, exiting")
}

This however destroys the stack trace origin of the signal.

Memory leak

Hello,
pipeline with appsrc to which flv video chunks are pushed with PushBuffer and NewBufferFromBytes() leaks memory. The memory continues to grow while the pipeline is running and stays after the pipeline has ended (EOS event followed with stateNull), and is never freed. The pipeline works and produces valid MP4 file. Gstreamer version is 1.22.0 and it is run on Debian 12.

appsrc (flv video)=>queue->flvdemux->audiotee->queue->aacparser->mp4mux->filesink
->videotee->queue->h264parser->mp4mux

memleak-bpfcc -p 15232 -o 5000 30

shows continous growing allocation of memory at :

54947840 bytes in 13415 allocations from stack
		0x000015480133d679	g_malloc+0x19 [libglib-2.0.so.0.7400.6]
		0x0000000000000001	[unknown]
		0x00001547c40280c0	[unknown]

debug/pprof at NewBufferFromBytes and wrapBuffer functions.
gst

Try to run an example on windows 11 fails

Try to run an example on Windows with Powershell and I saw the below error:
..\..\gst\control_source.go:44:162: cannot use _Ctype_ulong(time) (value of type _Ctype_ulong) as _Ctype_ulonglong value in variable declaration

could not determine kind of name for C.gst_element_factory_make_with_properties

Hello friends, I get this error when using the library. I use Ubuntu. Please help me

go run main.go                  
£ github.com/go-gst/go-gst/gst
../../../go/pkg/mod/github.com/go-gst/go-gst§v0.0.0-20240207190302-04ec17f96d71/gst/gst_element_factory.go:70:10: could not determine kind of name for C.gst_element_factory_make_with_properties

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.