Gstreamer, appsink element new-sample signal seems missing

appsrc and appsink are the two gstreamer elements designated to move buffered data in and out gstreamer pipeline into the wrapping app.
I was trying to connect "new-sample" signal from appsink
https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c#appsink::new-sample
But I'm getting:
/home/jack/.choosenim/toolchains/nim-1.4.2/lib/core/macros.nim(558, 3) Error: undeclared identifier: 'scnew_sample'
System:
apt-cache policy libgtk2.0-0 libgtk-3-0
libgtk2.0-0:
  Installed: 2.24.32-4ubuntu4
  Candidate: 2.24.32-4ubuntu4
  Version table:
 *** 2.24.32-4ubuntu4 500
        500 http://it.archive.ubuntu.com/ubuntu focal/main amd64 Packages
        100 /var/lib/dpkg/status
libgtk-3-0:
  Installed: 3.24.20-0ubuntu1
  Candidate: 3.24.20-0ubuntu1
  Version table:
 *** 3.24.20-0ubuntu1 500
        500 http://it.archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     3.24.18-1ubuntu1 500
        500 http://it.archive.ubuntu.com/ubuntu focal/main amd64 Packages

Heres a short snippet that exposed the problem:
import gintro/[gst, gobject, gtk]

const launchPipeline = """
    audiotestsrc wave=sine is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    opusenc frame-size=60 bitrate=96000 !
    rtpopuspay mtu=1200 max-ptime=50000000000000000 ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
    rtpt. ! queue ! udpsink host=<IP_ADDRESS> port=5555
"""

proc newSampleCallback(el: Element): object =
    echo "sample"

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = gst.getByName(cast[gst.Bin](pipeline), "sink")
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

Thanks

The actual problem seems to be that "new-sample" is not a valid signal for your sink variable.
I have to look at the C example tomorrow, as I don't know much about gstreamer myself. GStreamer support was asked for by someone some years ago, ,i added it and that guy vanished.
Maybe it is indeed possible to use gstreamer with dummygtk without a real gtk install, but it is hard to verify for me as I have full gtk installed. But first we would have to make it working at all.

The actual problem seems to be that "new-sample" is not a valid signal for your sink variable.
I have to look at the C example tomorrow, as I don't know much about gstreamer myself. GStreamer support was asked for by someone some years ago, ,i added it and that guy vanished.
Maybe it is indeed possible to use gstreamer with dummygtk without a real gtk install, but it is hard to verify for me as I have full gtk installed. But first we would have to make it working at all.

I've switched to gtk and dropped dummygtk and problem is the same. I've edited post and added gtk version and linux version.
"sink" should be is the appsink element declared in constant string (appsink name=sink emit-signals=true), I'm already using same pattern to edit pipelines on the fly like in this snippet here where I change the destination udp port for the udpsink element on the fly (actually requires "udpsink host=<IP_ADDRESS> port=5555 name=udps" in pipeline)
var  udps = gst.getByName(cast[gst.Bin](pipeline), "udps")
# Set property
var v: Value
discard init(v, typeFromName("guint"))
v.setUint(5554)
gobject.setProperty(udps, "port", v)
# Get property
gobject.getProperty(udps, "port", v)
echo gobject.getUint(v)

I've switched to gtk and dropped dummygtk and problem is the same. I've edited post and added gtk version and linux version.
"sink" should be is the appsink element declared in constant string (appsink name=sink emit-signals=true), I'm already using same pattern to edit pipelines on the fly like in this snippet here where I change the destination udp port for the udpsink element on the fly (actually requires "udpsink host=<IP_ADDRESS> port=5555 name=udps" in pipeline)
var  udps = gst.getByName(cast[gst.Bin](pipeline), "udps")
# Set property
var v: Value
discard init(v, typeFromName("guint"))
v.setUint(5554)
gobject.setProperty(udps, "port", v)
# Get property
gobject.getProperty(udps, "port", v)
echo gobject.getUint(v)

The fact is that we have no "new_sample" signal support for gintro at all.
grep "new_sample" ~/.nimble/pkgs/gintro-0.8.5/gintro/*
grep "new-sample" ~/.nimble/pkgs/gintro-0.8.5/gintro/*
One explanation would be that this signal is not supported by gobject-introspection.
Or, the problem may be that gstreamer has many modules and plugins, but gintro supports only the basic version. I have to inspect the gir files in /usr/share/gir-1.0 tomorrow and maybe ask Mr Bassi or Mr Droege.
Time to go to bed here, bye.

The fact is that we have no "new_sample" signal support for gintro at all.
grep "new_sample" ~/.nimble/pkgs/gintro-0.8.5/gintro/*
grep "new-sample" ~/.nimble/pkgs/gintro-0.8.5/gintro/*
One explanation would be that this signal is not supported by gobject-introspection.
Or, the problem may be that gstreamer has many modules and plugins, but gintro supports only the basic version. I have to inspect the gir files in /usr/share/gir-1.0 tomorrow and maybe ask Mr Bassi or Mr Droege.
Time to go to bed here, bye.

Here's the contents of my /usr/share/gir-1.0 and the position of the new-sample signal
➜  gir-1.0 ls
Atk-1.0.gir  GdkPixbuf-2.0.gir   Gst-1.0.gir            GstBase-1.0.gir        GstNet-1.0.gir      GstRtspServer-1.0.gir  Gtk-2.0.gir       Pango-1.0.gir       PangoOT-1.0.gir
GCalc-2.gir  GdkPixdata-2.0.gir  GstAllocators-1.0.gir  GstCheck-1.0.gir       GstPbutils-1.0.gir  GstSdp-1.0.gir         HarfBuzz-0.0.gir  PangoCairo-1.0.gir  PangoXft-1.0.gir
GCi-1.gir    GdkX11-2.0.gir      GstApp-1.0.gir         GstController-1.0.gir  GstRtp-1.0.gir      GstTag-1.0.gir         ICal-3.0.gir      PangoFc-1.0.gir
Gdk-2.0.gir  GMime-2.6.gir       GstAudio-1.0.gir       GstGL-1.0.gir          GstRtsp-1.0.gir     GstVideo-1.0.gir       ICalGLib-3.0.gir  PangoFT2-1.0.gir

➜  gir-1.0 rg -F "new-sample"
GstApp-1.0.gir
104:to %TRUE will make appsink emit the "new-sample" and "new-preroll" signals
376:             line="1198">Check if appsink will emit the "new-preroll" and "new-sample" signals.</doc>
381:               line="1204">%TRUE if @appsink is emiting the "new-preroll" and "new-sample"
658:             line="1175">Make appsink emit the "new-preroll" and "new-sample" signals. This option is
876:      <glib:signal name="new-sample" when="last">

Here's the contents of my /usr/share/gir-1.0 and the position of the new-sample signal
➜  gir-1.0 ls
Atk-1.0.gir  GdkPixbuf-2.0.gir   Gst-1.0.gir            GstBase-1.0.gir        GstNet-1.0.gir      GstRtspServer-1.0.gir  Gtk-2.0.gir       Pango-1.0.gir       PangoOT-1.0.gir
GCalc-2.gir  GdkPixdata-2.0.gir  GstAllocators-1.0.gir  GstCheck-1.0.gir       GstPbutils-1.0.gir  GstSdp-1.0.gir         HarfBuzz-0.0.gir  PangoCairo-1.0.gir  PangoXft-1.0.gir
GCi-1.gir    GdkX11-2.0.gir      GstApp-1.0.gir         GstController-1.0.gir  GstRtp-1.0.gir      GstTag-1.0.gir         ICal-3.0.gir      PangoFc-1.0.gir
Gdk-2.0.gir  GMime-2.6.gir       GstAudio-1.0.gir       GstGL-1.0.gir          GstRtsp-1.0.gir     GstVideo-1.0.gir       ICalGLib-3.0.gir  PangoFT2-1.0.gir

➜  gir-1.0 rg -F "new-sample"
GstApp-1.0.gir
104:to %TRUE will make appsink emit the "new-sample" and "new-preroll" signals
376:             line="1198">Check if appsink will emit the "new-preroll" and "new-sample" signals.</doc>
381:               line="1204">%TRUE if @appsink is emiting the "new-preroll" and "new-sample"
658:             line="1175">Make appsink emit the "new-preroll" and "new-sample" signals. This option is
876:      <glib:signal name="new-sample" when="last">

We would need GstApp, which again needs the larger GstBase. Maybe more modules are required. GstApp is not very large and the generator script processes it without problems, but unfortunately for GstApp there are some issues, which would need manually inspection. I think when we ship GstBase then we should ship also all the other gst modules. But we can not test them, we have no testing code.
So the question is: What do you really intent. Will providing more gst modules really pay off? For most gintro users gst is of course useless and only a source of potential bugs.
 Do you have some knowledge about gst, so that you can provide a small demo program for GstApp -- when not in Nim yet, then maybe in another language?

We would need GstApp, which again needs the larger GstBase. Maybe more modules are required. GstApp is not very large and the generator script processes it without problems, but unfortunately for GstApp there are some issues, which would need manually inspection. I think when we ship GstBase then we should ship also all the other gst modules. But we can not test them, we have no testing code.
So the question is: What do you really intent. Will providing more gst modules really pay off? For most gintro users gst is of course useless and only a source of potential bugs.
 Do you have some knowledge about gst, so that you can provide a small demo program for GstApp -- when not in Nim yet, then maybe in another language?

I had a short look at the issue generated by GstBase. The cause seems to be bugs in the gir file. For example an array which should be zero terminated is marked as not zero terminated, see
gst_bit_writer_free_and_get_data()
Fixing such bugs has to be done manually, or we would have to wait for upstream fixes which may never happen. These bugs exists as gstreamer devs are not closely related to gtk core devs, and these bugs remain udiscovered while no one use gir for gstreamer, when ever it is used then from plain C.
Will have to discuss the issues with Mr. Bassi and Mr. Droege from the Rust team.

I had a short look at the issue generated by GstBase. The cause seems to be bugs in the gir file. For example an array which should be zero terminated is marked as not zero terminated, see
gst_bit_writer_free_and_get_data()
Fixing such bugs has to be done manually, or we would have to wait for upstream fixes which may never happen. These bugs exists as gstreamer devs are not closely related to gtk core devs, and these bugs remain udiscovered while no one use gir for gstreamer, when ever it is used then from plain C.
Will have to discuss the issues with Mr. Bassi and Mr. Droege from the Rust team.

See
https://discourse.gnome.org/t/gst-bit-writer-free-and-get-data/5304/2

See
https://discourse.gnome.org/t/gst-bit-writer-free-and-get-data/5304/2

From my experience, appsink and appsrc are the elements required to provide gstreamer multimedia manipulation inside single process (instead moving buffers via IPC, or polling for samples) enabling the creation of a self-contained gstreamer application the right way.
Other solution would be to create a plugin: https://gstreamer.freedesktop.org/documentation/plugin-development/basics/index.html?gi-language=c
I'm not a C programmer, but I've been using gstreamer via python so far, which bindings are gir based afaik and officially supported by gstreamer team: https://gstreamer.freedesktop.org/modules/gst-python.html
There are some official python examples here:
https://gitlab.freedesktop.org/gstreamer/gst-python/-/tree/master/examples
Sadly no examples for appsink and appsrc there, but there are successful stories like:
http://lifestyletransfer.com/how-to-use-gstreamer-appsink-in-python/
https://gist.github.com/cbenhagen/76b24573fa63e7492fb6
https://github.com/jackersson/gst-python-tutorials/tree/master/launch_pipeline
more stuff can be found by following the 'connect "new-sample"' keywords.
If you think a minimal python example would be useful here, I can provide one.
This is how "new-sample" signal would be used in C: https://gstreamer.freedesktop.org/documentation/tutorials/basic/short-cutting-the-pipeline.html?gi-language=c

From my experience, appsink and appsrc are the elements required to provide gstreamer multimedia manipulation inside single process (instead moving buffers via IPC, or polling for samples) enabling the creation of a self-contained gstreamer application the right way.
Other solution would be to create a plugin: https://gstreamer.freedesktop.org/documentation/plugin-development/basics/index.html?gi-language=c
I'm not a C programmer, but I've been using gstreamer via python so far, which bindings are gir based afaik and officially supported by gstreamer team: https://gstreamer.freedesktop.org/modules/gst-python.html
There are some official python examples here:
https://gitlab.freedesktop.org/gstreamer/gst-python/-/tree/master/examples
Sadly no examples for appsink and appsrc there, but there are successful stories like:
http://lifestyletransfer.com/how-to-use-gstreamer-appsink-in-python/
https://gist.github.com/cbenhagen/76b24573fa63e7492fb6
https://github.com/jackersson/gst-python-tutorials/tree/master/launch_pipeline
more stuff can be found by following the 'connect "new-sample"' keywords.
If you think a minimal python example would be useful here, I can provide one.
This is how "new-sample" signal would be used in C: https://gstreamer.freedesktop.org/documentation/tutorials/basic/short-cutting-the-pipeline.html?gi-language=c

other solution that comes to my mind to solve this specific problem, is to link https://github.com/GStreamer/gst-plugins-base/blob/master/gst-libs/gst/app/gstappsink.h
to enable "gst_app_sink_pull_sample" function

other solution that comes to my mind to solve this specific problem, is to link https://github.com/GStreamer/gst-plugins-base/blob/master/gst-libs/gst/app/gstappsink.h
to enable "gst_app_sink_pull_sample" function

not sure why, but the only .so library where I find the symbol "gst_app_sink_pull_sample" exposed is "libgstwebrtc.so" in "/usr/lib/x86_64-linux-gnu/gstreamer-1.0"

not sure why, but the only .so library where I find the symbol "gst_app_sink_pull_sample" exposed is "libgstwebrtc.so" in "/usr/lib/x86_64-linux-gnu/gstreamer-1.0"

OK, I have added Base and App module, but had to block 4 functions for Base module for now.
You can install latest gintro with command
nimble install gintro@#head
Then this fixed code of you should compile and run -- but I have no idea if it does something intended:
import gintro/[gst, gstapp, gobject, gtk]

const launchPipeline = """
    audiotestsrc wave=sine is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    opusenc frame-size=60 bitrate=96000 !
    rtpopuspay mtu=1200 max-ptime=50000000000000000 ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
    rtpt. ! queue ! udpsink host=<IP_ADDRESS> port=5555
"""

# https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c#appsink::new-sample
#GstFlowReturn
#new_sample_callback (GstElement  appsink,
#                     gpointer udata)

proc newSampleCallback(el: AppSink): FlowReturn =
    echo "sample"

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

$ nim c --gc:arc t.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
................................CC: t.nim

Hint:  [Link]
Hint: 199067 lines; 3.396s; 353.75MiB peakmem; Debug build; proj: /tmp/hhh/t.nim; out: /tmp/hhh/t [SuccessX]
salewski@nuc /tmp/hhh $ ./t
sample
sample
sample

OK, I have added Base and App module, but had to block 4 functions for Base module for now.
You can install latest gintro with command
nimble install gintro@#head
Then this fixed code of you should compile and run -- but I have no idea if it does something intended:
import gintro/[gst, gstapp, gobject, gtk]

const launchPipeline = """
    audiotestsrc wave=sine is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    opusenc frame-size=60 bitrate=96000 !
    rtpopuspay mtu=1200 max-ptime=50000000000000000 ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
    rtpt. ! queue ! udpsink host=<IP_ADDRESS> port=5555
"""

# https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c#appsink::new-sample
#GstFlowReturn
#new_sample_callback (GstElement  appsink,
#                     gpointer udata)

proc newSampleCallback(el: AppSink): FlowReturn =
    echo "sample"

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

$ nim c --gc:arc t.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
................................CC: t.nim

Hint:  [Link]
Hint: 199067 lines; 3.396s; 353.75MiB peakmem; Debug build; proj: /tmp/hhh/t.nim; out: /tmp/hhh/t [SuccessX]
salewski@nuc /tmp/hhh $ ./t
sample
sample
sample

Super! It compiles and runs, just having some difficulties in freeing the sample with
https://gstreamer.freedesktop.org/documentation/gstreamer/gstsample.html?gi-language=c#gst_sample_unref
to declare sample consumption

Super!
Is gintro bindings doing anything about memory management?
Is gintro bindings doing anything about memory management? Should I import it manually for the moment?

reading the sample inside the callback with buffer.map(mapInfo, {MapFlag.read}) also brings some memory problems. It goes SIGSEGV immediatly with --gc:arc, and after a few seconds with --gc:refc (deallocating too soon?)
import gintro/[gst, gstapp, gobject, gtk]
import sugar

const launchPipeline = """
    audiotestsrc wave=sine is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    lamemp3enc target=bitrate bitrate=96 cbr=true !
    rtpmpapay mtu=1200 ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
"""

# https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c#appsink::new-sample
#GstFlowReturn
#new_sample_callback (GstElement  appsink,
#                     gpointer udata)

proc newSampleCallback(sink: AppSink): FlowReturn =
    var sample: gst.Sample = sink.pullSample
    var buffer: gst.Buffer = sample.getBuffer
    dump buffer.typeof
    dump buffer.getSizeBuffer
    dump buffer.nMemory
    var mapInfo: gst.MapInfo00
    var mapBool = buffer.map(mapInfo, {MapFlag.read})
    #dump mapBool
    #var memory = buffer.getMemory(0)
    #dump memory.get
    result = FlowReturn.ok

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

Hint: /home/jack/nim/src/gstreamerAppSink  [Exec]
typeof(buffer) = Buffer
getSizeBuffer(buffer) = 1168
nMemory(buffer) = 6
Traceback (most recent call last)
/home/jack/nim/src/gstreamerAppSink.nim(50) gstreamerAppSink
/home/jack/nim/src/gstreamerAppSink.nim(46) main
/home/jack/.nimble/pkgs/gintro-#head/gintro/gst.nim(13256) timedPopFiltered
/home/jack/.choosenim/toolchains/nim-1.4.2/lib/core/macros.nim(559) connect_for_signal_cdecl_new_sample1
/home/jack/nim/src/gstreamerAppSink.nim(24) newSampleCallback
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Error: execution of an external program failed: '/home/jack/nim/src/gstreamerAppSink '

this is how it should work
https://stackoverflow.com/questions/35390673/gstreamer-1-0-get-data-from-gstsample-in-gstappsink

reading the sample inside the callback with buffer.map(mapInfo, {MapFlag.read}) also brings some memory problems. It goes SIGSEGV immediatly with --gc:arc, and after a few seconds with --gc:refc (deallocating too soon?)
import gintro/[gst, gstapp, gobject, gtk]
import sugar

const launchPipeline = """
    audiotestsrc wave=sine is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    lamemp3enc target=bitrate bitrate=96 cbr=true !
    rtpmpapay mtu=1200 ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
"""

# https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c#appsink::new-sample
#GstFlowReturn
#new_sample_callback (GstElement  appsink,
#                     gpointer udata)

proc newSampleCallback(sink: AppSink): FlowReturn =
    var sample: gst.Sample = sink.pullSample
    var buffer: gst.Buffer = sample.getBuffer
    dump buffer.typeof
    dump buffer.getSizeBuffer
    dump buffer.nMemory
    var mapInfo: gst.MapInfo00
    var mapBool = buffer.map(mapInfo, {MapFlag.read})
    #dump mapBool
    #var memory = buffer.getMemory(0)
    #dump memory.get
    result = FlowReturn.ok

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

Hint: /home/jack/nim/src/gstreamerAppSink  [Exec]
typeof(buffer) = Buffer
getSizeBuffer(buffer) = 1168
nMemory(buffer) = 6
Traceback (most recent call last)
/home/jack/nim/src/gstreamerAppSink.nim(50) gstreamerAppSink
/home/jack/nim/src/gstreamerAppSink.nim(46) main
/home/jack/.nimble/pkgs/gintro-#head/gintro/gst.nim(13256) timedPopFiltered
/home/jack/.choosenim/toolchains/nim-1.4.2/lib/core/macros.nim(559) connect_for_signal_cdecl_new_sample1
/home/jack/nim/src/gstreamerAppSink.nim(24) newSampleCallback
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Error: execution of an external program failed: '/home/jack/nim/src/gstreamerAppSink '

this is how it should work
https://stackoverflow.com/questions/35390673/gstreamer-1-0-get-data-from-gstsample-in-gstappsink

Is gintro bindings doing anything about memory management?

Yes of course is gintro doing fully automatic memory management. One exception can be cairo drawing, when ARC is not used, as default refc GC may do too much delay.
Unfortunately Gstreamer and libnice are really difficult, and I know not much about both. GStreamer has this strange MiniMessage, which is not really a GObject, but similar. So we may have to do some debugging. When we have working C code it generally helps. Will have a closer look tomorrow.

Is gintro bindings doing anything about memory management?

Yes of course is gintro doing fully automatic memory management. One exception can be cairo drawing, when ARC is not used, as default refc GC may do too much delay.
Unfortunately Gstreamer and libnice are really difficult, and I know not much about both. GStreamer has this strange MiniMessage, which is not really a GObject, but similar. So we may have to do some debugging. When we have working C code it generally helps. Will have a closer look tomorrow.

GstSample seems to be a Boxed type. And for those Mr Bassi told us that we should use gboxedfree from bindings, so we have
~/.nimble/pkgs/gintro-0.8.5/gintro/gst.nim
type
  Sample00* {.pure.} = object
  Sample* = ref object
    impl*: ptr Sample00
    ignoreFinalizer*: bool

proc gst_sample_get_type*(): GType {.importc, libprag.}

proc gBoxedFreeGstSample*(self: Sample) =
  if not self.ignoreFinalizer:
    boxedFree(gst_sample_get_type(), cast[ptr Sample00](self.impl))

when defined(gcDestructors):
  proc `=destroy`*(self: var typeof(Sample()[])) =
    if not self.ignoreFinalizer and self.impl != nil:
      boxedFree(gst_sample_get_type(), cast[ptr Sample00](self.impl))
      self.impl = nil

proc newWithFinalizer*(x: var Sample) =
  when defined(gcDestructors):
    new(x)
  else:
    new(x, gBoxedFreeGstSample)

Of course there may be bugs.

GstSample seems to be a Boxed type. And for those Mr Bassi told us that we should use gboxedfree from bindings, so we have
~/.nimble/pkgs/gintro-0.8.5/gintro/gst.nim
type
  Sample00* {.pure.} = object
  Sample* = ref object
    impl*: ptr Sample00
    ignoreFinalizer*: bool

proc gst_sample_get_type*(): GType {.importc, libprag.}

proc gBoxedFreeGstSample*(self: Sample) =
  if not self.ignoreFinalizer:
    boxedFree(gst_sample_get_type(), cast[ptr Sample00](self.impl))

when defined(gcDestructors):
  proc `=destroy`*(self: var typeof(Sample()[])) =
    if not self.ignoreFinalizer and self.impl != nil:
      boxedFree(gst_sample_get_type(), cast[ptr Sample00](self.impl))
      self.impl = nil

proc newWithFinalizer*(x: var Sample) =
  when defined(gcDestructors):
    new(x)
  else:
    new(x, gBoxedFreeGstSample)

Of course there may be bugs.

ok, but I don't get how I should use it. Sample is being returned by sink.pullSample and gBoxedFreeGstSample doesn't have a return value. Maybe I should use "proc newWithFinalizer*(x: var Sample)"
proc newSampleCallback(sink: AppSink): FlowReturn =
    dump sink.isEos()
    dump sink.isNil()
    var sample: gst.Sample = sink.pullSample
    sample.gBoxedFreeGstSample
    var buffer: gst.Buffer = sample.getBuffer
    buffer.gBoxedFreeGstBuffer
    dump buffer.typeof
    dump buffer.getSizeBuffer
    dump buffer.nMemory
    var mapInfo: gst.MapInfo00
    var mapBool = buffer.map(mapInfo, {MapFlag.read})  # <- SIGSEGV here, seems to depend on GC
    dump mapBool
    #var memory = buffer.getMemory(0)
    #dump memory.get
    result = FlowReturn.ok

ok, but I don't get how I should use it. Sample is being returned by sink.pullSample and gBoxedFreeGstSample doesn't have a return value. Maybe I should use "proc newWithFinalizer*(x: var Sample)"
proc newSampleCallback(sink: AppSink): FlowReturn =
    dump sink.isEos()
    dump sink.isNil()
    var sample: gst.Sample = sink.pullSample
    sample.gBoxedFreeGstSample
    var buffer: gst.Buffer = sample.getBuffer
    buffer.gBoxedFreeGstBuffer
    dump buffer.typeof
    dump buffer.getSizeBuffer
    dump buffer.nMemory
    var mapInfo: gst.MapInfo00
    var mapBool = buffer.map(mapInfo, {MapFlag.read})  # <- SIGSEGV here, seems to depend on GC
    dump mapBool
    #var memory = buffer.getMemory(0)
    #dump memory.get
    result = FlowReturn.ok

You should not explicit free anything with gintro. Exception may be cairo with refc GC. When you think you have to really free something manually, then we have to patch the modules to do no double free.
But I get your last example not to work, I really don't know much about gstreamer. A working C code would help.
For your last code I get
$ ./t2
/tmp/hhh/t2.nim(51)      t2
/tmp/hhh/t2.nim(37)      main
/home/salewski/.nimble/pkgs/gintro-0.8.5/gintro/gst.nim(16592) parseLaunch
Error: unhandled exception: no element "lamemp3enc" [GException]

No idea currently, will continue tomorrow. Maybe you have a friend who can provide you with a working C example, then I can translate it to Nim. But without is is hard for me.

You should not explicit free anything with gintro. Exception may be cairo with refc GC. When you think you have to really free something manually, then we have to patch the modules to do no double free.
But I get your last example not to work, I really don't know much about gstreamer. A working C code would help.
For your last code I get
$ ./t2
/tmp/hhh/t2.nim(51)      t2
/tmp/hhh/t2.nim(37)      main
/home/salewski/.nimble/pkgs/gintro-0.8.5/gintro/gst.nim(16592) parseLaunch
Error: unhandled exception: no element "lamemp3enc" [GException]

No idea currently, will continue tomorrow. Maybe you have a friend who can provide you with a working C example, then I can translate it to Nim. But without is is hard for me.

I may need media-plugins/gst-plugins-lame-1.16. Will try tomorrow.
$ locate lamemp3enc
/usr/share/gtk-doc/html/gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-lamemp3enc.html
salewski@nuc /tmp/hhh $ emerge -pv gst-plugins-good

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] media-libs/gst-plugins-good-1.16.2:1.0::gentoo  USE="nls orc" 0 KiB

Total: 1 package (1 reinstall), Size of downloads: 0 KiB
salewski@nuc /tmp/hhh $ emerge -pv gst-plugins-lame

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N     ] media-plugins/gst-plugins-lame-1.16.2:1.0::gentoo  0 KiB

Total: 1 package (1 new), Size of downloads: 0 KiB

I may need media-plugins/gst-plugins-lame-1.16. Will try tomorrow.
$ locate lamemp3enc
/usr/share/gtk-doc/html/gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-lamemp3enc.html
salewski@nuc /tmp/hhh $ emerge -pv gst-plugins-good

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] media-libs/gst-plugins-good-1.16.2:1.0::gentoo  USE="nls orc" 0 KiB

Total: 1 package (1 reinstall), Size of downloads: 0 KiB
salewski@nuc /tmp/hhh $ emerge -pv gst-plugins-lame

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N     ] media-plugins/gst-plugins-lame-1.16.2:1.0::gentoo  0 KiB

Total: 1 package (1 new), Size of downloads: 0 KiB

Have to learn what gst_buffer_map() and MapInfo is tomorrow. Really time to go to bed here. Bye.
$ grep -A14 gst_buffer_map ~/.nimble/pkgs/gintro-0.8.5/gintro/gst.nim
proc gst_buffer_map(self: ptr Buffer00; info: var MapInfo00; flags: MapFlags): gboolean {.
    importc, libprag.}

proc map*(self: Buffer; info: var MapInfo00; flags: MapFlags): bool =
  toBool(gst_buffer_map(cast[ptr Buffer00](self.impl), info, flags))

Have to learn what gst_buffer_map() and MapInfo is tomorrow. Really time to go to bed here. Bye.
$ grep -A14 gst_buffer_map ~/.nimble/pkgs/gintro-0.8.5/gintro/gst.nim
proc gst_buffer_map(self: ptr Buffer00; info: var MapInfo00; flags: MapFlags): gboolean {.
    importc, libprag.}

proc map*(self: Buffer; info: var MapInfo00; flags: MapFlags): bool =
  toBool(gst_buffer_map(cast[ptr Buffer00](self.impl), info, flags))

Please find here a working C example of what I am trying to achieve: a full appsink -> my app -> appsrc pipeline
https://fossies.org/linux/gst-plugins-base/tests/examples/app/appsink-src.c
you can compile it with:
libtool --mode=link gcc $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-app-1.0) -o appsink-src appsink-src.c
and you can run it by passing a wav file path as first argument:
./appsink-src myfile.wav
Uploading myfile.zip… <- quick wav for testing
this application will sandwich appsink+appsrc between this pipeline:
filesrc location="<wavfilepath>" ! wavparse ! audioconvert ! audioresample ! appsink caps="audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved" name=testsink
and this pipeline:
appsrc name=testsource caps="audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved" ! autoaudiosink
it means that gstreamer will read the wav file, convert it to raw pcm S16LE, mono, 8KHz, and pass buffers to appsink (named testsink) that will signal "new-sample" when new buffer lands in appsink. Callback "on_new_sample_from_sink" will be executed and lines 44:67 will grab the newly available buffer, copy it and send it unmodified to "testsource" (that is the name of the appsrc element in second pipeline) basically glueing  the two creating a single flow of data from filesrc to autoaudiosink, that will make you hear the wav file, demostrating how to create and application to intercept data passing inside pipeline.
without the application in the middle, the same pipeline can be executed independently via command line with the gst-launch-1.0 tool that comes with gstreamer installation
$ gst-launch-1.0 filesrc location="myfile.wav" ! wavparse ! audioconvert ! audioresample ! audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved ! autoaudiosink
a full list of currently installed elements can be obtained with
$ gst-inspect-1.0
This example is not reading the data contained into the buffer, just passing to appsrc. What I need to do is reading the data and modify the buffer inside the callback, and for that I think map iswhat should be used.
proc map*(self: Buffer; info: var MapInfo00; flags: MapFlags): bool =
  toBool(gst_buffer_map(cast[ptr Buffer00](self.impl), info, flags))

gstreamer library is a collection of elements splitted into different packages, lamemp3enc element is contained into plugins-good, that for gentoo would be: https://packages.gentoo.org/packages/media-libs/gst-plugins-good

Please find here a working C example of what I am trying to achieve: a full appsink -> my app -> appsrc pipeline
https://fossies.org/linux/gst-plugins-base/tests/examples/app/appsink-src.c
you can compile it with:
libtool --mode=link gcc $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-app-1.0) -o appsink-src appsink-src.c
and you can run it by passing a wav file path as first argument:
./appsink-src myfile.wav
Uploading myfile.zip… <- quick wav for testing
this application will sandwich appsink+appsrc between this pipeline:
filesrc location="<wavfilepath>" ! wavparse ! audioconvert ! audioresample ! appsink caps="audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved" name=testsink
and this pipeline:
appsrc name=testsource caps="audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved" ! autoaudiosink
it means that gstreamer will read the wav file, convert it to raw pcm S16LE, mono, 8KHz, and pass buffers to appsink (named testsink) that will signal "new-sample" when new buffer lands in appsink. Callback "on_new_sample_from_sink" will be executed and lines 44:67 will grab the newly available buffer, copy it and send it unmodified to "testsource" (that is the name of the appsrc element in second pipeline) basically glueing  the two creating a single flow of data from filesrc to autoaudiosink, that will make you hear the wav file, demostrating how to create and application to intercept data passing inside pipeline.
without the application in the middle, the same pipeline can be executed independently via command line with the gst-launch-1.0 tool that comes with gstreamer installation
$ gst-launch-1.0 filesrc location="myfile.wav" ! wavparse ! audioconvert ! audioresample ! audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved ! autoaudiosink
a full list of currently installed elements can be obtained with
$ gst-inspect-1.0
This example is not reading the data contained into the buffer, just passing to appsrc. What I need to do is reading the data and modify the buffer inside the callback, and for that I think map iswhat should be used.
proc map*(self: Buffer; info: var MapInfo00; flags: MapFlags): bool =
  toBool(gst_buffer_map(cast[ptr Buffer00](self.impl), info, flags))

gstreamer library is a collection of elements splitted into different packages, lamemp3enc element is contained into plugins-good, that for gentoo would be: https://packages.gentoo.org/packages/media-libs/gst-plugins-good

GStreamer has this strange MiniMessage, which is not really a GObject, but similar.

GstMiniObject subclasses can be handled like simple boxed types, which is how it works in most other bindings. Manually binding GstMiniObjects however can bring additional advantages and a more flexible and convenient API in the bindings, especially in languages without GC. For example mapping the copy-on-write functionality and related safe multi-threaded "borrowing" to the target language can be quite useful, see the Rust bindings.
gobject-introspection is unfortunately very limited and only allows to express standard OOP patterns and little else.

Have to learn what gst_buffer_map() and MapInfo is tomorrow. Really time to go to bed here. Bye.

gst_buffer_map() is probably missing a caller allocates annotation for the GstMapInfo parameter. The way how it's supposed to be used is that the caller allocates (usually on the stack) a GstMapInfo, that is then passed into gst_buffer_map() and filled by it. The buffer that is passed in must stay valid until gst_buffer_unmap() is called, and gst_buffer_unmap() must be called at some point to avoid data from leaking.
Also the data inside the GstMapInfo is read-only or read-write depending on the GstMapFlags. If Nim has a concept of mutability this should ideally be taken into account here.

GStreamer has this strange MiniMessage, which is not really a GObject, but similar.

GstMiniObject subclasses can be handled like simple boxed types, which is how it works in most other bindings. Manually binding GstMiniObjects however can bring additional advantages and a more flexible and convenient API in the bindings, especially in languages without GC. For example mapping the copy-on-write functionality and related safe multi-threaded "borrowing" to the target language can be quite useful, see the Rust bindings.
gobject-introspection is unfortunately very limited and only allows to express standard OOP patterns and little else.

Have to learn what gst_buffer_map() and MapInfo is tomorrow. Really time to go to bed here. Bye.

gst_buffer_map() is probably missing a caller allocates annotation for the GstMapInfo parameter. The way how it's supposed to be used is that the caller allocates (usually on the stack) a GstMapInfo, that is then passed into gst_buffer_map() and filled by it. The buffer that is passed in must stay valid until gst_buffer_unmap() is called, and gst_buffer_unmap() must be called at some point to avoid data from leaking.
Also the data inside the GstMapInfo is read-only or read-write depending on the GstMapFlags. If Nim has a concept of mutability this should ideally be taken into account here.

@sdroege
Thank you for your help. You are right, I think the GstMapInfo entity was declared wrong in the Nim bindings. It was declared as a heavy symbol with a Nim proxy object. But from expecting the Gst C API docs it seems to make sense to handle GstMapInfo as a plain object, which is generally allocated in C and in Nim just on the stack, and which fields are exposed. This is like other plain objects are used in Nim, like TextIter or RGBColor and many more. We had a discussion about distinction of "heavy" and "light" entities some months ago, you confirmed my impression that it is not really possible to discover the right kind with gobject-introspection.
At least I got his latest example to compile and run with the MapInfo chance now:
import gintro/[gst, gstapp, gobject, gtk]
import sugar

const launchPipeline = """
    audiotestsrc wave=sine is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    lamemp3enc target=bitrate bitrate=96 cbr=true !
    rtpmpapay mtu=1200 ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
"""

# https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c#appsink::new-sample
#GstFlowReturn
#new_sample_callback (GstElement  appsink,
#                     gpointer udata)

proc newSampleCallback(sink: AppSink): FlowReturn =
    var sample: gst.Sample = sink.pullSample
    assert sample != nil
    assert sample.impl != nil
    var buffer: gst.Buffer = sample.getBuffer
    assert buffer != nil
    assert buffer.impl != nil
    dump buffer.typeof
    dump buffer.getSizeBuffer
    dump buffer.nMemory
    var mapInfo: gst.MapInfo
    var mapBool = buffer.map(mapInfo, {MapFlag.read})
    dump mapBool
    var memory = buffer.getMemory(0)
    #dump memory.get
    result = FlowReturn.ok

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

salewski@nuc ~/hhh $ nim c --gc:arc t2.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
..................................
/home/salewski/hhh/t2.nim(30, 9) Hint: 'memory' is declared but not used [XDeclaredButNotUsed]
Hint:  [Link]
Hint: 199529 lines; 3.360s; 353.102MiB peakmem; Debug build; proj: /home/salewski/hhh/t2.nim; out: /home/salewski/hhh/t2 [SuccessX]
salewski@nuc ~/hhh $ ./t2
typeof(buffer) = Buffer
getSizeBuffer(buffer) = 1168
nMemory(buffer) = 6
mapBool = true
typeof(buffer) = Buffer
getSizeBuffer(buffer) = 1168
nMemory(buffer) = 6
mapBool = true

@sdroege
Thank you for your help. You are right, I think the GstMapInfo entity was declared wrong in the Nim bindings. It was declared as a heavy symbol with a Nim proxy object. But from expecting the Gst C API docs it seems to make sense to handle GstMapInfo as a plain object, which is generally allocated in C and in Nim just on the stack, and which fields are exposed. This is like other plain objects are used in Nim, like TextIter or RGBColor and many more. We had a discussion about distinction of "heavy" and "light" entities some months ago, you confirmed my impression that it is not really possible to discover the right kind with gobject-introspection.
At least I got his latest example to compile and run with the MapInfo chance now:
import gintro/[gst, gstapp, gobject, gtk]
import sugar

const launchPipeline = """
    audiotestsrc wave=sine is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    lamemp3enc target=bitrate bitrate=96 cbr=true !
    rtpmpapay mtu=1200 ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
"""

# https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c#appsink::new-sample
#GstFlowReturn
#new_sample_callback (GstElement  appsink,
#                     gpointer udata)

proc newSampleCallback(sink: AppSink): FlowReturn =
    var sample: gst.Sample = sink.pullSample
    assert sample != nil
    assert sample.impl != nil
    var buffer: gst.Buffer = sample.getBuffer
    assert buffer != nil
    assert buffer.impl != nil
    dump buffer.typeof
    dump buffer.getSizeBuffer
    dump buffer.nMemory
    var mapInfo: gst.MapInfo
    var mapBool = buffer.map(mapInfo, {MapFlag.read})
    dump mapBool
    var memory = buffer.getMemory(0)
    #dump memory.get
    result = FlowReturn.ok

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

salewski@nuc ~/hhh $ nim c --gc:arc t2.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
..................................
/home/salewski/hhh/t2.nim(30, 9) Hint: 'memory' is declared but not used [XDeclaredButNotUsed]
Hint:  [Link]
Hint: 199529 lines; 3.360s; 353.102MiB peakmem; Debug build; proj: /home/salewski/hhh/t2.nim; out: /home/salewski/hhh/t2 [SuccessX]
salewski@nuc ~/hhh $ ./t2
typeof(buffer) = Buffer
getSizeBuffer(buffer) = 1168
nMemory(buffer) = 6
mapBool = true
typeof(buffer) = Buffer
getSizeBuffer(buffer) = 1168
nMemory(buffer) = 6
mapBool = true

@arkanoid87
I have fixed MapInfo data type and your last example, see above.
After a new
nimble install gintro@#head
it should compile and run for you.
I had to do
emerge -av gst-plugins-lame
to get the plugins working, the gst-plugins-good seems not to cover it.
I will try to convert your linked C example
https://fossies.org/linux/gst-plugins-base/tests/examples/app/appsink-src.c
this evening or in the next days.

@arkanoid87
I have fixed MapInfo data type and your last example, see above.
After a new
nimble install gintro@#head
it should compile and run for you.
I had to do
emerge -av gst-plugins-lame
to get the plugins working, the gst-plugins-good seems not to cover it.
I will try to convert your linked C example
https://fossies.org/linux/gst-plugins-base/tests/examples/app/appsink-src.c
this evening or in the next days.

Ok, great :) If you run into any other GStreamer-related problems here, feel free to simply CC me in the issues.

Ok, great :) If you run into any other GStreamer-related problems here, feel free to simply CC me in the issues.

I can confirm correct buffers from MapInfo in appsink new-sample callback!
I'm now going to try appsrc too, just like C code.
Thanks a lot for your effort on this

I can confirm correct buffers from MapInfo in appsink new-sample callback!
I'm now going to try appsrc too, just like C code.
Thanks a lot for your effort on this

This is the basic shape of the Nim version. Will continue tomorrow:
##  gcc -Wall appsink-src.c -o appsink-src $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-audio-1.0 gstreamer-app-1.0)
##  GStreamer
##
##  appsink-src.c: example for using appsink and appsrc.
##
##  Copyright (C) 2008 Wim Taymans<EMAIL_ADDRESS>##

import gintro/[gst, gstapp, gobject]

proc toBoolVal(b: bool): Value =
  let gtype = typeFromName("gboolean")
  discard init(result, gtype)
  setBoolean(result, b)

proc toUIntVal(i: int): Value =
  let gtype = typeFromName("guint")
  discard init(result, gtype)
  setUint(result, i)

##  these are the caps we are going to pass through the appsink and appsrc
const
  audioCaps = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

var audio_caps*: ptr gchar = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

type
  ProgramData = object
    loop: MainLoop
    source: gst.Element
    sink: gst.Element

##  called when the appsink notifies us that there is a new buffer ready for
##  processing
proc onNewSampleFromSink(elt: gst.Element; data: ProgramData): gst.FlowReturn =
  var
    sample: gst.Sample
    appBuffer: gst.Buffer
    buffer: gst.Buffer
    source: gst.Element
    ret: gst.FlowReturn
  ##  get the sample from appsink
  sample = elr.pull()
  buffer = sample.getBuffer(sample)
  ##  make a copy
  appBuffer = buffer.copy()
  ##  we don't need the appsink sample anymore
  # gst_sample_unref(sample)
  ##  get source an push new buffer
  # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
  source = getByName(data.sink, "testsource")
  ret = source.pushBuffer(appBuffer)
  # gst_object_unref(source)
  return ret

##  called when we get a GstMessage from the source pipeline when we get EOS, we
##  notify the appsrc of it.
proc onSourceMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  var source: gst.Element
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("The source got dry")
    # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
    source = getByName(data.sink, "testsource")
    # gst_app_src_end_of_stream(GST_APP_SRC(source))
    endOfStream(source)
    # gst_object_unref(source)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

##  called when we get a GstMessage from the sink pipeline when we get EOS, we
##  exit the mainloop and this testapp.
proc onSinkMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  ##  nil
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("Finished playback")
    glib.quit(data.loop)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

proc main =

  ##  Parse arguments
  let argc = paramCount() + 1
  var argv = newSeq[string](argc)
  for i in 0 ..< argc:
    argv[i] = paramStr(i)

  var
    filename: string
    data: ProgramData
    str: string
    bus: gst.Bus
    testsink: gst.Element
    testsource: gst.Element

  gst.init()
  if argc == 2:
    filename = argv[1]
  else:
    filename = "/usr/share/sounds/ekiga/ring.wav"
  if not fileTest(filename, FileTest.exists):
    echo("File $1 does not exist" % [filename])
    # g_free(filename)
    return quit(QuitFailure)
  data = g_new0(ProgramData, 1)
  data.loop = glib.newMainLoop(nil, false)
  ##  setting up source pipeline, we read from a file and convert to our desired
  ##  caps.
  string = "filesrc location=\"$1\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"$2\" name=testsink" % [filename, audioCaps])
  #g_free(filename)
  data.source = gst.parseLaunch(string, nil)
  #g_free(string)
  if data.source == nil:
    echo("Bad source")
    # g_main_loop_unref(data.loop)
    # g_free(data)
    quit(QuitFailure)
  bus = gst.getBus(data.source)
  gst.addWatch(bus, onSourceMessage, data)
  # gst_object_unref(bus)
  ##  we use appsink in push mode, it sends us a signal when data is available
  ##  and we pull out the data in the signal callback. We want the appsink to
  ##  push as fast as it can, hence the sync=false
  # testsink = gst_bin_get_by_name(GST_BIN(data.source), "testsink")
  testsink = getByName(data.source, "testsink")
  # g_object_set(G_OBJECT(testsink), "emit-signals", TRUE, "sync", FALSE, nil)

  setProperty(testsink, "emit-signals", toBoolVal(true))

  setProperty(testsink, "sync", toBoolVal(false))

  connect(testsink, "new-sample", onNewSampleFromSink, data)
  #gst_object_unref(testsink)
  ##  setting up sink pipeline, we push audio data into this pipeline that will
  ##  then play it back using the default audio sink. We have no blocking
  ##  behaviour on the src which means that we will push the entire file into
  ##  memory.
  string = "appsrc name=testsource caps=\"$1\" ! autoaudiosink" % [audioCaps])
  data.sink = gst.parseLaunch(string, nil)
  #g_free(string)
  if data.sink == nil:
    echo("Bad sink")
    #gst_object_unref(data.source)
    #g_main_loop_unref(data.loop)
    #g_free(data)
    quit(QuitFailure)
  testsource = gst.getByName(data.sink, "testsource")
  ##  configure for time-based format
  setProperty(testsource, "format", toUIntVal(Format.time.ord))
  #g_object_set(testsource, "format", GST_FORMAT_TIME, nil)
  ##  uncomment the next line to block when appsrc has buffered enough
  ##  g_object_set (testsource, "block", TRUE, NULL);
  #gst_object_unref(testsource)
  bus = getBus(data.sink)
  addWatch(bus, onSinkMessage, data)
  #gst_object_unref(bus)
  ##  launching things
  setState(data.sink, State.playing)
  setState(data.source, State.playing)
  ##  let's run !, this loop will quit when the sink pipeline goes EOS or when an
  ##  error occurs in the source or sink pipelines.
  echo("Let\'s run!")
  glib.run(data.loop)
  echo("Going out")
  setState(data.source, State.null)
  setState(data.sink, State.null)
  # gst_object_unref(data.source)
  # gst_object_unref(data.sink)
  # g_main_loop_unref(data.loop)
  # g_free(data)
  quit(QuitSuccess)

This is the basic shape of the Nim version. Will continue tomorrow:
##  gcc -Wall appsink-src.c -o appsink-src $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-audio-1.0 gstreamer-app-1.0)
##  GStreamer
##
##  appsink-src.c: example for using appsink and appsrc.
##
##  Copyright (C) 2008 Wim Taymans<EMAIL_ADDRESS>##

import gintro/[gst, gstapp, gobject]

proc toBoolVal(b: bool): Value =
  let gtype = typeFromName("gboolean")
  discard init(result, gtype)
  setBoolean(result, b)

proc toUIntVal(i: int): Value =
  let gtype = typeFromName("guint")
  discard init(result, gtype)
  setUint(result, i)

##  these are the caps we are going to pass through the appsink and appsrc
const
  audioCaps = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

var audio_caps*: ptr gchar = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

type
  ProgramData = object
    loop: MainLoop
    source: gst.Element
    sink: gst.Element

##  called when the appsink notifies us that there is a new buffer ready for
##  processing
proc onNewSampleFromSink(elt: gst.Element; data: ProgramData): gst.FlowReturn =
  var
    sample: gst.Sample
    appBuffer: gst.Buffer
    buffer: gst.Buffer
    source: gst.Element
    ret: gst.FlowReturn
  ##  get the sample from appsink
  sample = elr.pull()
  buffer = sample.getBuffer(sample)
  ##  make a copy
  appBuffer = buffer.copy()
  ##  we don't need the appsink sample anymore
  # gst_sample_unref(sample)
  ##  get source an push new buffer
  # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
  source = getByName(data.sink, "testsource")
  ret = source.pushBuffer(appBuffer)
  # gst_object_unref(source)
  return ret

##  called when we get a GstMessage from the source pipeline when we get EOS, we
##  notify the appsrc of it.
proc onSourceMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  var source: gst.Element
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("The source got dry")
    # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
    source = getByName(data.sink, "testsource")
    # gst_app_src_end_of_stream(GST_APP_SRC(source))
    endOfStream(source)
    # gst_object_unref(source)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

##  called when we get a GstMessage from the sink pipeline when we get EOS, we
##  exit the mainloop and this testapp.
proc onSinkMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  ##  nil
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("Finished playback")
    glib.quit(data.loop)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

proc main =

  ##  Parse arguments
  let argc = paramCount() + 1
  var argv = newSeq[string](argc)
  for i in 0 ..< argc:
    argv[i] = paramStr(i)

  var
    filename: string
    data: ProgramData
    str: string
    bus: gst.Bus
    testsink: gst.Element
    testsource: gst.Element

  gst.init()
  if argc == 2:
    filename = argv[1]
  else:
    filename = "/usr/share/sounds/ekiga/ring.wav"
  if not fileTest(filename, FileTest.exists):
    echo("File $1 does not exist" % [filename])
    # g_free(filename)
    return quit(QuitFailure)
  data = g_new0(ProgramData, 1)
  data.loop = glib.newMainLoop(nil, false)
  ##  setting up source pipeline, we read from a file and convert to our desired
  ##  caps.
  string = "filesrc location=\"$1\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"$2\" name=testsink" % [filename, audioCaps])
  #g_free(filename)
  data.source = gst.parseLaunch(string, nil)
  #g_free(string)
  if data.source == nil:
    echo("Bad source")
    # g_main_loop_unref(data.loop)
    # g_free(data)
    quit(QuitFailure)
  bus = gst.getBus(data.source)
  gst.addWatch(bus, onSourceMessage, data)
  # gst_object_unref(bus)
  ##  we use appsink in push mode, it sends us a signal when data is available
  ##  and we pull out the data in the signal callback. We want the appsink to
  ##  push as fast as it can, hence the sync=false
  # testsink = gst_bin_get_by_name(GST_BIN(data.source), "testsink")
  testsink = getByName(data.source, "testsink")
  # g_object_set(G_OBJECT(testsink), "emit-signals", TRUE, "sync", FALSE, nil)

  setProperty(testsink, "emit-signals", toBoolVal(true))

  setProperty(testsink, "sync", toBoolVal(false))

  connect(testsink, "new-sample", onNewSampleFromSink, data)
  #gst_object_unref(testsink)
  ##  setting up sink pipeline, we push audio data into this pipeline that will
  ##  then play it back using the default audio sink. We have no blocking
  ##  behaviour on the src which means that we will push the entire file into
  ##  memory.
  string = "appsrc name=testsource caps=\"$1\" ! autoaudiosink" % [audioCaps])
  data.sink = gst.parseLaunch(string, nil)
  #g_free(string)
  if data.sink == nil:
    echo("Bad sink")
    #gst_object_unref(data.source)
    #g_main_loop_unref(data.loop)
    #g_free(data)
    quit(QuitFailure)
  testsource = gst.getByName(data.sink, "testsource")
  ##  configure for time-based format
  setProperty(testsource, "format", toUIntVal(Format.time.ord))
  #g_object_set(testsource, "format", GST_FORMAT_TIME, nil)
  ##  uncomment the next line to block when appsrc has buffered enough
  ##  g_object_set (testsource, "block", TRUE, NULL);
  #gst_object_unref(testsource)
  bus = getBus(data.sink)
  addWatch(bus, onSinkMessage, data)
  #gst_object_unref(bus)
  ##  launching things
  setState(data.sink, State.playing)
  setState(data.source, State.playing)
  ##  let's run !, this loop will quit when the sink pipeline goes EOS or when an
  ##  error occurs in the source or sink pipelines.
  echo("Let\'s run!")
  glib.run(data.loop)
  echo("Going out")
  setState(data.source, State.null)
  setState(data.sink, State.null)
  # gst_object_unref(data.source)
  # gst_object_unref(data.sink)
  # g_main_loop_unref(data.loop)
  # g_free(data)
  quit(QuitSuccess)

I've noticed that appsink work with --gc:arc but goes SIGSEGV with default GC after some seconds.
Is this a real problem? Should I just stick with --gc:arc?
Here's a minimal example to reproduce the problem. It generates some test audio (ticks) and writes to gstreamerAppSink_out.mp3
import gintro/[gst, gstapp, gobject, gtk]

const launchPipeline = """
    audiotestsrc wave=ticks is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    lamemp3enc target=bitrate bitrate=96 cbr=true ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
"""

var outFile = open("gstreamerAppSink_out.mp3", fmWrite)

proc newSampleCallback(sink: AppSink): FlowReturn =
    var sample: gst.Sample = sink.pullSample
    assert sample != nil
    var buffer: gst.Buffer = sample.getBuffer
    var mapInfo: gst.MapInfo
    discard buffer.map(mapInfo, {MapFlag.read})
    discard outFile.writeBuffer(mapInfo.data, mapInfo.size)
    result = FlowReturn.ok

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

I've noticed that appsink work with --gc:arc but goes SIGSEGV with default GC after some seconds.
Is this a real problem? Should I just stick with --gc:arc?
Here's a minimal example to reproduce the problem. It generates some test audio (ticks) and writes to gstreamerAppSink_out.mp3
import gintro/[gst, gstapp, gobject, gtk]

const launchPipeline = """
    audiotestsrc wave=ticks is-live=true !
    audio/x-raw, format=S16LE, rate=48000, channels=1, layout=interleaved !
    lamemp3enc target=bitrate bitrate=96 cbr=true ! tee name=rtpt
    rtpt. ! queue ! appsink name=sink emit-signals=true
"""

var outFile = open("gstreamerAppSink_out.mp3", fmWrite)

proc newSampleCallback(sink: AppSink): FlowReturn =
    var sample: gst.Sample = sink.pullSample
    assert sample != nil
    var buffer: gst.Buffer = sample.getBuffer
    var mapInfo: gst.MapInfo
    discard buffer.map(mapInfo, {MapFlag.read})
    discard outFile.writeBuffer(mapInfo.data, mapInfo.size)
    result = FlowReturn.ok

proc main =
  var pipeline: gst.Element
  var bus: gst.Bus
  var msg: gst.Message

  gst.init()
  pipeline = gst.parseLaunch(launchPipeline)

  # Testing pipeline manipulation
  var sink = cast[AppSink](gst.getByName(cast[gst.Bin](pipeline), "sink"))
  connect(sink, "new-sample", newSampleCallback)

  #  Start playing
  discard gst.setState(pipeline, gst.State.playing)
  #  Wait until error or EOS
  bus = gst.getBus(pipeline)
  msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  echo msg.getType
  discard gst.setState(pipeline, gst.State.null) # is this necessary?

main()

I've noticed that appsink work with --gc:arc but goes SIGSEGV with default GC after some seconds.
Is this a real problem? Should I just stick with --gc:arc?

That should not occur. With default refc freeing resources is delayed. Generally that can hide bugs, so I always do test with ARC first. For 60 frames per sec cairo drawing delayed freeing may be a problem, so I added manually destroy functions. I never really had problems with cairo, Nim and refc GC. But we had some issues 10 years ago with Ruby GTK and cairo drawing. For video/audio delayed destroy may be a problem, at least it can generate out of memory. Maybe other resources get exhausted too?
Will try to investigate that in the next days further.
Current issue is
appBuffer = buffer.copy()

my gst bindings seems to have only a deep copy variant. Will investigate later...

I've noticed that appsink work with --gc:arc but goes SIGSEGV with default GC after some seconds.
Is this a real problem? Should I just stick with --gc:arc?

That should not occur. With default refc freeing resources is delayed. Generally that can hide bugs, so I always do test with ARC first. For 60 frames per sec cairo drawing delayed freeing may be a problem, so I added manually destroy functions. I never really had problems with cairo, Nim and refc GC. But we had some issues 10 years ago with Ruby GTK and cairo drawing. For video/audio delayed destroy may be a problem, at least it can generate out of memory. Maybe other resources get exhausted too?
Will try to investigate that in the next days further.
Current issue is
appBuffer = buffer.copy()

my gst bindings seems to have only a deep copy variant. Will investigate later...

The gst_buffer_copy() is solved by
https://discourse.gnome.org/t/gst-buffer-copy-is-missing-in-gir-file/5327
when it should really work that way. But we need a macro for
gst_bus_add_watch()
similar as what we have in
gimplglib.nim for g_io_add_watch().
I am not really good in  creating macros, so it may be 3 hours more. Will try in the next days.

The gst_buffer_copy() is solved by
https://discourse.gnome.org/t/gst-buffer-copy-is-missing-in-gir-file/5327
when it should really work that way. But we need a macro for
gst_bus_add_watch()
similar as what we have in
gimplglib.nim for g_io_add_watch().
I am not really good in  creating macros, so it may be 3 hours more. Will try in the next days.

I tried to fix https://github.com/StefanSalewski/gintro/issues/108#issuecomment-758212648 by minimal changes and now it compiles and runs, at least for a few seconds :P I can hear some samples of output audio then GC errors out (even with arc).
Here the show stoppers I've found along the way (TODOs in code comments), no surprises:

buffer.copy() <- missing
gst.addWatch(bus, PRIORITY_DEFAULT, onSourceMessage, data) <- third argument is of type BusFunc
type BusFunc* = proc (bus: ptr Bus00; message: ptr Message00; userData: pointer): gboolean {.cdecl.}

I've just commented the three lines so onSourceMessage and onSinkMessage are never called and buffer is never copied, but yet it at least I got some audio out and this means that pushing to appsrc works. Made my day.
##  gcc -Wall appsink-src.c -o appsink-src $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-audio-1.0 gstreamer-app-1.0)
##  GStreamer
##
##  appsink-src.c: example for using appsink and appsrc.
##
##  Copyright (C) 2008 Wim Taymans<EMAIL_ADDRESS>##

import gintro/[gtk, gst, glib, gstapp, gobject]
from os import paramCount, paramStr
import strutils

proc toBoolVal(b: bool): Value =
  let gtype = typeFromName("gboolean")
  discard init(result, gtype)
  setBoolean(result, b)

proc toUIntVal(i: int): Value =
  let gtype = typeFromName("guint")
  discard init(result, gtype)
  setUint(result, i)

##  these are the caps we are going to pass through the appsink and appsrc
const
  audioCaps = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

# var audio_caps*: ptr gchar = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

type
  ProgramData = ref object
    loop: MainLoop
    source: gst.Element
    sink: gst.Element

##  called when the appsink notifies us that there is a new buffer ready for
##  processing
proc onNewSampleFromSink(elt: gstapp.AppSink; data: ProgramData): gst.FlowReturn =
  var
    sample: gst.Sample
    appBuffer: gst.Buffer
    buffer: gst.Buffer
    source: gstapp.AppSrc
    ret: gst.FlowReturn
  ##  get the sample from appsink
  sample = elt.pullSample()
  buffer = sample.getBuffer()
  ##  make a copy
  # appBuffer = buffer.copy() # <-- TODO needs fix
  appBuffer = buffer
  ##  we don't need the appsink sample anymore
  # gst_sample_unref(sample)
  ##  get source an push new buffer
  # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
  source = cast[gstapp.AppSrc](getByName(cast[gst.Bin](data.sink), "testsource"))
  ret = source.pushBuffer(appBuffer)
  # gst_object_unref(source)
  return ret

##  called when we get a GstMessage from the source pipeline when we get EOS, we
##  notify the appsrc of it.
proc onSourceMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  var source: gstapp.AppSrc
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("The source got dry")
    # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
    source = cast[gstapp.AppSrc](getByName(cast[gst.Bin](data.sink), "testsource"))
    # gst_app_src_end_of_stream(GST_APP_SRC(source))
    discard endOfStream(source)
    # gst_object_unref(source)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

##  called when we get a GstMessage from the sink pipeline when we get EOS, we
##  exit the mainloop and this testapp.
proc onSinkMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  ##  nil
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("Finished playback")
    glib.quit(data.loop)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

proc main =

  ##  Parse arguments
  let argc = paramCount() + 1
  var argv = newSeq[string](argc)
  for i in 0 ..< argc:
    argv[i] = paramStr(i)

  var
    filename: string
    data: ProgramData
    str: string
    bus: gst.Bus
    testsink: gstapp.AppSink
    testsource: gstapp.AppSrc

  gst.init()
  if argc == 2:
    filename = argv[1]
  else:
    filename = "/usr/share/sounds/ekiga/ring.wav"
  if not fileTest(filename, FileTest.exists):
    echo("File $1 does not exist" % [filename])
    # g_free(filename)
    quit(QuitFailure)
  # data = g_new0(ProgramData, 1)
  data = ProgramData()
  data.loop = glib.newMainLoop(nil, false)
  ##  setting up source pipeline, we read from a file and convert to our desired
  ##  caps.
  var srcLaunchString = "filesrc location=\"$1\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"$2\" name=testsink" % [filename, audioCaps]
  #g_free(filename)
  data.source = gst.parseLaunch(srcLaunchString)
  #g_free(string)
  if data.source == nil:
    echo("Bad source")
    # g_main_loop_unref(data.loop)
    # g_free(data)
    quit(QuitFailure)
  bus = gst.getBus(data.source)
  # gst.addWatch(bus, PRIORITY_DEFAULT, onSourceMessage, data)  TODO Needs fix on BusFunc
  # gst_object_unref(bus)
  ##  we use appsink in push mode, it sends us a signal when data is available
  ##  and we pull out the data in the signal callback. We want the appsink to
  ##  push as fast as it can, hence the sync=false
  # testsink = gst_bin_get_by_name(GST_BIN(data.source), "testsink")
  testsink = cast[gstapp.AppSink](getByName(cast[gst.Bin](data.source), "testsink"))

  # g_object_set(G_OBJECT(testsink), "emit-signals", TRUE, "sync", FALSE, nil)

  setProperty(testsink, "emit-signals", toBoolVal(true))

  setProperty(testsink, "sync", toBoolVal(false))

  connect(testsink, "new-sample", onNewSampleFromSink, data)
  #gst_object_unref(testsink)
  ##  setting up sink pipeline, we push audio data into this pipeline that will
  ##  then play it back using the default audio sink. We have no blocking
  ##  behaviour on the src which means that we will push the entire file into
  ##  memory.
  var sinkLaunchString = "appsrc name=testsource caps=\"$1\" ! autoaudiosink" % [audioCaps]
  data.sink = gst.parseLaunch(sinkLaunchString)
  #g_free(string)
  if data.sink == nil:
    echo("Bad sink")
    #gst_object_unref(data.source)
    #g_main_loop_unref(data.loop)
    #g_free(data)
    quit(QuitFailure)
  testsource = cast[gstapp.AppSrc](getByName(cast[gst.Bin](data.sink), "testsource"))

  ##  configure for time-based format
  setProperty(testsource, "format", toUIntVal(Format.time.ord))
  #g_object_set(testsource, "format", GST_FORMAT_TIME, nil)
  ##  uncomment the next line to block when appsrc has buffered enough
  ##  g_object_set (testsource, "block", TRUE, NULL);
  #gst_object_unref(testsource)
  bus = getBus(data.sink)
  # gst.addWatch(bus, PRIORITY_DEFAULT, onSinkMessage, data) TODO needs fix
  #gst_object_unref(bus)
  ##  launching things
  discard setState(data.sink, State.playing)
  discard setState(data.source, State.playing)
  ##  let's run !, this loop will quit when the sink pipeline goes EOS or when an
  ##  error occurs in the source or sink pipelines.
  echo("Let\'s run!")
  glib.run(data.loop)
  echo("Going out")
  discard setState(data.source, State.null)
  discard setState(data.sink, State.null)
  # gst_object_unref(data.source)
  # gst_object_unref(data.sink)
  # g_main_loop_unref(data.loop)
  # g_free(data)
  quit(QuitSuccess)

main()

I tried to fix https://github.com/StefanSalewski/gintro/issues/108#issuecomment-758212648 by minimal changes and now it compiles and runs, at least for a few seconds :P I can hear some samples of output audio then GC errors out (even with arc).
Here the show stoppers I've found along the way (TODOs in code comments), no surprises:

buffer.copy() <- missing
gst.addWatch(bus, PRIORITY_DEFAULT, onSourceMessage, data) <- third argument is of type BusFunc
type BusFunc* = proc (bus: ptr Bus00; message: ptr Message00; userData: pointer): gboolean {.cdecl.}

I've just commented the three lines so onSourceMessage and onSinkMessage are never called and buffer is never copied, but yet it at least I got some audio out and this means that pushing to appsrc works. Made my day.
##  gcc -Wall appsink-src.c -o appsink-src $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-audio-1.0 gstreamer-app-1.0)
##  GStreamer
##
##  appsink-src.c: example for using appsink and appsrc.
##
##  Copyright (C) 2008 Wim Taymans<EMAIL_ADDRESS>##

import gintro/[gtk, gst, glib, gstapp, gobject]
from os import paramCount, paramStr
import strutils

proc toBoolVal(b: bool): Value =
  let gtype = typeFromName("gboolean")
  discard init(result, gtype)
  setBoolean(result, b)

proc toUIntVal(i: int): Value =
  let gtype = typeFromName("guint")
  discard init(result, gtype)
  setUint(result, i)

##  these are the caps we are going to pass through the appsink and appsrc
const
  audioCaps = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

# var audio_caps*: ptr gchar = "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved"

type
  ProgramData = ref object
    loop: MainLoop
    source: gst.Element
    sink: gst.Element

##  called when the appsink notifies us that there is a new buffer ready for
##  processing
proc onNewSampleFromSink(elt: gstapp.AppSink; data: ProgramData): gst.FlowReturn =
  var
    sample: gst.Sample
    appBuffer: gst.Buffer
    buffer: gst.Buffer
    source: gstapp.AppSrc
    ret: gst.FlowReturn
  ##  get the sample from appsink
  sample = elt.pullSample()
  buffer = sample.getBuffer()
  ##  make a copy
  # appBuffer = buffer.copy() # <-- TODO needs fix
  appBuffer = buffer
  ##  we don't need the appsink sample anymore
  # gst_sample_unref(sample)
  ##  get source an push new buffer
  # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
  source = cast[gstapp.AppSrc](getByName(cast[gst.Bin](data.sink), "testsource"))
  ret = source.pushBuffer(appBuffer)
  # gst_object_unref(source)
  return ret

##  called when we get a GstMessage from the source pipeline when we get EOS, we
##  notify the appsrc of it.
proc onSourceMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  var source: gstapp.AppSrc
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("The source got dry")
    # source = gst_bin_get_by_name(GST_BIN(data.sink), "testsource")
    source = cast[gstapp.AppSrc](getByName(cast[gst.Bin](data.sink), "testsource"))
    # gst_app_src_end_of_stream(GST_APP_SRC(source))
    discard endOfStream(source)
    # gst_object_unref(source)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

##  called when we get a GstMessage from the sink pipeline when we get EOS, we
##  exit the mainloop and this testapp.
proc onSinkMessage(bus: gst.Bus; message: gst.Message; data: ProgramData): bool =
  ##  nil
  var h = message.impl.type
  if h == {MessageFlag.eos}:
    echo("Finished playback")
    glib.quit(data.loop)
  elif h == {MessageFlag.error}:
    echo("Received error")
    glib.quit(data.loop)
  else:
    discard
  return true

proc main =

  ##  Parse arguments
  let argc = paramCount() + 1
  var argv = newSeq[string](argc)
  for i in 0 ..< argc:
    argv[i] = paramStr(i)

  var
    filename: string
    data: ProgramData
    str: string
    bus: gst.Bus
    testsink: gstapp.AppSink
    testsource: gstapp.AppSrc

  gst.init()
  if argc == 2:
    filename = argv[1]
  else:
    filename = "/usr/share/sounds/ekiga/ring.wav"
  if not fileTest(filename, FileTest.exists):
    echo("File $1 does not exist" % [filename])
    # g_free(filename)
    quit(QuitFailure)
  # data = g_new0(ProgramData, 1)
  data = ProgramData()
  data.loop = glib.newMainLoop(nil, false)
  ##  setting up source pipeline, we read from a file and convert to our desired
  ##  caps.
  var srcLaunchString = "filesrc location=\"$1\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"$2\" name=testsink" % [filename, audioCaps]
  #g_free(filename)
  data.source = gst.parseLaunch(srcLaunchString)
  #g_free(string)
  if data.source == nil:
    echo("Bad source")
    # g_main_loop_unref(data.loop)
    # g_free(data)
    quit(QuitFailure)
  bus = gst.getBus(data.source)
  # gst.addWatch(bus, PRIORITY_DEFAULT, onSourceMessage, data)  TODO Needs fix on BusFunc
  # gst_object_unref(bus)
  ##  we use appsink in push mode, it sends us a signal when data is available
  ##  and we pull out the data in the signal callback. We want the appsink to
  ##  push as fast as it can, hence the sync=false
  # testsink = gst_bin_get_by_name(GST_BIN(data.source), "testsink")
  testsink = cast[gstapp.AppSink](getByName(cast[gst.Bin](data.source), "testsink"))

  # g_object_set(G_OBJECT(testsink), "emit-signals", TRUE, "sync", FALSE, nil)

  setProperty(testsink, "emit-signals", toBoolVal(true))

  setProperty(testsink, "sync", toBoolVal(false))

  connect(testsink, "new-sample", onNewSampleFromSink, data)
  #gst_object_unref(testsink)
  ##  setting up sink pipeline, we push audio data into this pipeline that will
  ##  then play it back using the default audio sink. We have no blocking
  ##  behaviour on the src which means that we will push the entire file into
  ##  memory.
  var sinkLaunchString = "appsrc name=testsource caps=\"$1\" ! autoaudiosink" % [audioCaps]
  data.sink = gst.parseLaunch(sinkLaunchString)
  #g_free(string)
  if data.sink == nil:
    echo("Bad sink")
    #gst_object_unref(data.source)
    #g_main_loop_unref(data.loop)
    #g_free(data)
    quit(QuitFailure)
  testsource = cast[gstapp.AppSrc](getByName(cast[gst.Bin](data.sink), "testsource"))

  ##  configure for time-based format
  setProperty(testsource, "format", toUIntVal(Format.time.ord))
  #g_object_set(testsource, "format", GST_FORMAT_TIME, nil)
  ##  uncomment the next line to block when appsrc has buffered enough
  ##  g_object_set (testsource, "block", TRUE, NULL);
  #gst_object_unref(testsource)
  bus = getBus(data.sink)
  # gst.addWatch(bus, PRIORITY_DEFAULT, onSinkMessage, data) TODO needs fix
  #gst_object_unref(bus)
  ##  launching things
  discard setState(data.sink, State.playing)
  discard setState(data.source, State.playing)
  ##  let's run !, this loop will quit when the sink pipeline goes EOS or when an
  ##  error occurs in the source or sink pipelines.
  echo("Let\'s run!")
  glib.run(data.loop)
  echo("Going out")
  discard setState(data.source, State.null)
  discard setState(data.sink, State.null)
  # gst_object_unref(data.source)
  # gst_object_unref(data.sink)
  # g_main_loop_unref(data.loop)
  # g_free(data)
  quit(QuitSuccess)

main()

now it compiles and runs

That is a nice result already.
I will try to create the macro for gst_bus_add_watch() today, then we should have all together. My macros are unfortunately a bit ugly always, one serious disadvantage for all my macros is that the last optional parameter can be not a var parameter. But I guess the core devs are still too busy to help -- and they do not like gtk that much and do not know much about it.

now it compiles and runs

That is a nice result already.
I will try to create the macro for gst_bus_add_watch() today, then we should have all together. My macros are unfortunately a bit ugly always, one serious disadvantage for all my macros is that the last optional parameter can be not a var parameter. But I guess the core devs are still too busy to help -- and they do not like gtk that much and do not know much about it.

Got the addWatch() macro ready. And it compiles and plays wav files!
Will integrate the macro into the gintro package later this day and then push to github.

Got the addWatch() macro ready. And it compiles and plays wav files!
Will integrate the macro into the gintro package later this day and then push to github.

actually I got how addWatch call can be fixed with a macro, but I didn't get how to deal with gst_buffer_copy() and gst_mini_object_copy()
do we have to wait gobject instrospection on thato function to be fixed upstream? https://discourse.gnome.org/t/gst-buffer-copy-is-missing-in-gir-file/5327

actually I got how addWatch call can be fixed with a macro, but I didn't get how to deal with gst_buffer_copy() and gst_mini_object_copy()
do we have to wait gobject instrospection on thato function to be fixed upstream? https://discourse.gnome.org/t/gst-buffer-copy-is-missing-in-gir-file/5327

OK, I have pushed it to github. Install with
nimble install gintro@#head
The example file appsink_src.nim
is located in the eamples/gtk3 directory.
Unfortunately it can crash. I tested with
./appsink_src /usr/share/sounds/alsa/Front_Center.wav
When compiled with
nim c --gc:arc appsink_src.nim
it mostly works for me but in rare cases crash. Compiled with default GC it seems to always crash.
I have no idea about the location of the crash currently. For debugging you may ask for help on Nim IRC or try yourself. I am too tired for today.
The addWatch() macro is located in file ~/gintro/gintro/gimplgst.nim
I have not done carefully proofreading yet, maybe there is an error? The gst_buffer_copy() is substituted manually by
$ tail -12 ~/.nimble/pkgs/gintro-#head/gintro/gst.nim

# https://discourse.gnome.org/t/gst-buffer-copy-is-missing-in-gir-file/5327
# GstMiniObject * gst_mini_object_copy (const GstMiniObject *mini_object);
proc gst_buffer_copy(self: ptr Buffer00): ptr Buffer00 {.
    importc: "gst_mini_object_copy", libprag.}

proc copy*(self: Buffer): Buffer =
  fnew(result, gBoxedFreeGstBuffer)
  result.impl = gst_buffer_copy(cast[ptr Buffer00](self.impl))

include gimplgst

As suggested by Mr. Droege. May be the reason for crashes too?
The addWatch() macro can be beautified for sure. Would be nice when the optional parameter could be var. And destroyNotify is always nil currently.
 We would have to investigate why they are there and how we can avoid them.

OK, I have pushed it to github. Install with
nimble install gintro@#head
The example file appsink_src.nim
is located in the eamples/gtk3 directory.
Unfortunately it can crash. I tested with
./appsink_src /usr/share/sounds/alsa/Front_Center.wav
When compiled with
nim c --gc:arc appsink_src.nim
it mostly works for me but in rare cases crash. Compiled with default GC it seems to always crash.
I have no idea about the location of the crash currently. For debugging you may ask for help on Nim IRC or try yourself. I am too tired for today.
The addWatch() macro is located in file ~/gintro/gintro/gimplgst.nim
I have not done carefully proofreading yet, maybe there is an error? The gst_buffer_copy() is substituted manually by
$ tail -12 ~/.nimble/pkgs/gintro-#head/gintro/gst.nim

# https://discourse.gnome.org/t/gst-buffer-copy-is-missing-in-gir-file/5327
# GstMiniObject * gst_mini_object_copy (const GstMiniObject *mini_object);
proc gst_buffer_copy(self: ptr Buffer00): ptr Buffer00 {.
    importc: "gst_mini_object_copy", libprag.}

proc copy*(self: Buffer): Buffer =
  fnew(result, gBoxedFreeGstBuffer)
  result.impl = gst_buffer_copy(cast[ptr Buffer00](self.impl))

include gimplgst

As suggested by Mr. Droege. May be the reason for crashes too?
The addWatch() macro can be beautified for sure. Would be nice when the optional parameter could be var. And destroyNotify is always nil currently.
 We would have to investigate why they are there and how we can avoid them.

And destroyNotify is always nil currently.

You should never expose destroy notify parameters (anywhere, not only for this function) in bindings for languages with memory management.

And destroyNotify is always nil currently.

You should never expose destroy notify parameters (anywhere, not only for this function) in bindings for languages with memory management.

That is really a funny bug!
Random crashes, also with gc:none. Strange valgrinds reports. So I assumed some memory corruption. But as I am still tired and lazy, I just compiled with -d:danger. And it works without any problems now.
No crash in 50 calls, tested with arc, orc and refc. No valgrind issues! And no idea.
salewski@nuc ~/hhh $ nim c --gc:orc -d:danger appsink_src.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
...................................
Hint:  [Link]
Hint: 205116 lines; 2.728s; 355.75MiB peakmem; Dangerous Release build; proj: /home/salewski/hhh/appsink_src.nim; out: /home/salewski/hhh/appsink_src [SuccessX]

salewski@nuc ~/hhh $ valgrind ./appsink_src /usr/share/sounds/alsa/Front_Center.wav
==14672== Memcheck, a memory error detector
==14672== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14672== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==14672== Command: ./appsink_src /usr/share/sounds/alsa/Front_Center.wav
==14672==
--14672-- WARNING: unhandled amd64-linux syscall: 315
--14672-- You may be able to write your own handler.
--14672-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--14672-- Nevertheless we consider this a bug.  Please report
--14672-- it at http://valgrind.org/support/bug_reports.html.
Let's run!
The source got dry
Finished playback
Going out
==14672==
==14672== HEAP SUMMARY:
==14672==     in use at exit: 1,426,846 bytes in 16,489 blocks
==14672==   total heap usage: 32,170 allocs, 15,681 frees, 4,097,654 bytes allocated
==14672==
==14672== LEAK SUMMARY:
==14672==    definitely lost: 456 bytes in 9 blocks
==14672==    indirectly lost: 0 bytes in 0 blocks
==14672==      possibly lost: 6,084 bytes in 77 blocks
==14672==    still reachable: 1,329,402 bytes in 16,072 blocks
==14672==                       of which reachable via heuristic:
==14672==                         length64           : 640 bytes in 16 blocks
==14672==                         newarray           : 1,584 bytes in 19 blocks
==14672==         suppressed: 0 bytes in 0 blocks
==14672== Rerun with --leak-check=full to see details of leaked memory
==14672==
==14672== For lists of detected and suppressed errors, rerun with: -s
==14672== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

That is really a funny bug!
Random crashes, also with gc:none. Strange valgrinds reports. So I assumed some memory corruption. But as I am still tired and lazy, I just compiled with -d:danger. And it works without any problems now.
No crash in 50 calls, tested with arc, orc and refc. No valgrind issues! And no idea.
salewski@nuc ~/hhh $ nim c --gc:orc -d:danger appsink_src.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
...................................
Hint:  [Link]
Hint: 205116 lines; 2.728s; 355.75MiB peakmem; Dangerous Release build; proj: /home/salewski/hhh/appsink_src.nim; out: /home/salewski/hhh/appsink_src [SuccessX]

salewski@nuc ~/hhh $ valgrind ./appsink_src /usr/share/sounds/alsa/Front_Center.wav
==14672== Memcheck, a memory error detector
==14672== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14672== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==14672== Command: ./appsink_src /usr/share/sounds/alsa/Front_Center.wav
==14672==
--14672-- WARNING: unhandled amd64-linux syscall: 315
--14672-- You may be able to write your own handler.
--14672-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--14672-- Nevertheless we consider this a bug.  Please report
--14672-- it at http://valgrind.org/support/bug_reports.html.
Let's run!
The source got dry
Finished playback
Going out
==14672==
==14672== HEAP SUMMARY:
==14672==     in use at exit: 1,426,846 bytes in 16,489 blocks
==14672==   total heap usage: 32,170 allocs, 15,681 frees, 4,097,654 bytes allocated
==14672==
==14672== LEAK SUMMARY:
==14672==    definitely lost: 456 bytes in 9 blocks
==14672==    indirectly lost: 0 bytes in 0 blocks
==14672==      possibly lost: 6,084 bytes in 77 blocks
==14672==    still reachable: 1,329,402 bytes in 16,072 blocks
==14672==                       of which reachable via heuristic:
==14672==                         length64           : 640 bytes in 16 blocks
==14672==                         newarray           : 1,584 bytes in 19 blocks
==14672==         suppressed: 0 bytes in 0 blocks
==14672== Rerun with --leak-check=full to see details of leaked memory
==14672==
==14672== For lists of detected and suppressed errors, rerun with: -s
==14672== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

even more strange, if you replace line
str = "filesrc location=\"$1\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"$2\" name=testsink" % [filename, audioCaps]
with
str = "audiotestsrc is-live=true ! audioconvert ! audioresample ! appsink caps=\"$2\" name=testsink" % [filename, audioCaps]
it will play an infinite source (sine wave)
if I run this version normally I hear multiple clicks per second (seems one per buffer), but same program inside valgrind doesn't have this problem. Is valgrind fixing buffers? How's possible.
With an endless source, is also easier to reproduce the memory issues
with refc I reach crash after ~20s
Let's run!
Traceback (most recent call last)
/home/jack/nim/src/gstreamerStefan.nim(171) gstreamerStefan
/home/jack/nim/src/gstreamerStefan.nim(161) main
/home/jack/.choosenim/toolchains/nim-1.4.2/lib/core/macros.nim(559) connect_for_signal_cdecl_new_sample1
/home/jack/nim/src/gstreamerStefan.nim(42) onNewSampleFromSink
/home/jack/.nimble/pkgs/gintro-#head/gintro/gst.nim(3585) getBuffer
/home/jack/.choosenim/toolchains/nim-1.4.2/lib/system/gc.nim(439) newObj
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

with valgrind:

Click to expand
==8827== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8827== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==8827== Command: ./src/gstreamerStefan /home/jack/gstreamer/appsink_minimal/myfile.wav
==8827==
--8827-- WARNING: unhandled amd64-linux syscall: 315
--8827-- You may be able to write your own handler.
--8827-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--8827-- Nevertheless we consider this a bug.  Please report
--8827-- it at http://valgrind.org/support/bug_reports.html.
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x673F565: pa_shm_cleanup (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-13.99.so)
==8827==    by 0x673F7A1: pa_shm_create_rw (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-13.99.so)
==8827==    by 0x672F4B6: pa_mempool_new (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-13.99.so)
==8827==    by 0x66B49B1: pa_context_new_with_proplist (in /usr/lib/x86_64-linux-gnu/libpulse.so.0.21.2)
==8827==    by 0x5C7C02C: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstpulseaudio.so)
==8827==    by 0x5CC8252: gst_audio_ring_buffer_open_device (in /usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0.1602.0)
==8827==    by 0x5CE9238: ??? (in /usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0.1602.0)
==8827==    by 0x5C80CDA: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstpulseaudio.so)
==8827==    by 0x51939F1: gst_element_change_state (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.1602.0)
==8827==    by 0x5194138: ??? (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.1602.0)
==8827==    by 0x5C6C75A: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstautodetect.so)
==8827==    by 0x51939F1: gst_element_change_state (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.1602.0)
==8827==
Let's run!
==8827== Thread 6 queue0:src:
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x111484: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x111484: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x111484: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1114C6: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Use of uninitialised value of size 8
==8827==    at 0x10AECA: intSetGet__O3FRrWKKUdi8uRTGxiPdIg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x10AFFE: contains__9b5xR7VBZVwQDvk5Nr9bDKdQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x10B1E7: isAccessible__EZspgz843pJ9adnD0ZpJO6wsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x10B736: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1114C6: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1114C6: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1114C6: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115AB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115AB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115AB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115EB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115EB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115EB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11162B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11162B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11162B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11154B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11154B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11154B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11160B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11160B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11160B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11156B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11156B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11156B: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x1112C1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115CB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x50DA805: g_cclosure_marshal_generic_va (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6400.3)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB32: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115CB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1241E3: connect_for_signal_cdecl_new_sample1__hAfnzYKKbRAt0mGW7mSzDA (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x512BFF4: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==    by 0x512B409: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0)
==8827==
==8827== Conditional jump or move depends on uninitialised value(s)
==8827==    at 0x10BB63: interiorAllocatedPtr__NuzKjA4SX9afyji9cHHIuKpQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1112E1: gcMark__x5SbLN3uVBCsEa67N20nPwsystem (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1115CB: markStackAndRegisters__U6T7JWtDLrWhtmhXSoy9a6g (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x116EC4: collectCTBody__XHio9cMpnLoH7GyCj1Z9besg_2 (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x1170D8: collectCT__XHio9cMpnLoH7GyCj1Z9besg (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x117580: rawNewObj__ehkAaLROrd0Hc9aLROWt1nQ (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x11336E: newObj (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x120E80: getBuffer__A5QNWLo7YKlTob3wAUEMtw (in /home/jack/nim/src/gstreamerStefan)
==8827==    by 0x124088: onNewSampleFromSink__3NT9bOeQNRCcyiEuC68245g (in /home/jack/nim/src/gstreamerStefan)