Okok, i finally got the gst-example working.
It was necessary to change the buffer.c and buffer.h file in the gstreamer sources from
https://gstreamer.freedesktop.org/src/gstreamer/. I used the 1.2.0 version. The files are found in gstreamer-1.2.0/gs/.
I added the the function in gstreamer-1.2.0/gst/buffer.c
void
gst_buffer_unref (GstBuffer * buf)
{
gst_mini_object_unref (GST_MINI_OBJECT_CAST (buf));
}
And changed this lines in buffer.h:
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC void gst_buffer_unref (GstBuffer * buf);
#endif
static inline void
gst_buffer_unref (GstBuffer * buf)
{
gst_mini_object_unref (GST_MINI_OBJECT_CAST (buf));
}
into this:
void gst_buffer_unref (GstBuffer * buf);
I found a helpful shellscript for compiling gst here: http://kacianka.at/?p=145. I split it in two files, one for downloading and one for compiling so I can edit the files in between. This script does not add the .so files to the system. So its necessary to add the exact path to the new binaries in gst.xtm found in extempore/libs/external/. The shared libraries are found in the new directory created by the script gstreamer_build/lib/. Of course the last thing I had to do was adding the gst_buffer_unref - function to gst.xtm so I can access it in extempore by adding the line:
(bind-lib gstlib gst_buffer_unref [void,GstBuffer*]*)
Now the follwing code reads a v4l device and streams the video into "inframedata". This array can be uploaded to a gl texture,...
(bind-val inwidth i32 1024) (bind-val inheight i32 768)
(bind-val datsize i64 (* 3 (i32toi64 inwidth) (i32toi64 inheight)))
(bind-val inframedata i8*)
(bind-val vplay1 i1 0)
(bind-type userdata <i32,GstElement*>)
(bind-func init_sample_data
(lambda ()
(set! inframedata (malloc datsize))
void))
(bind-func init
(lambda ()
(gst_init null null)))
(bind-func new_preroll
(lambda (sink:GstAppSink* data:gpointer)
(let ((sample (gst_app_sink_pull_preroll (cast sink i8*)))
(caps (gst_sample_get_caps sample))
(st (gst_caps_get_structure caps 0))
(gv (gst_structure_get_value st "framerate"))
(num (gst_value_get_fraction_numerator gv))
(denom (gst_value_get_fraction_denominator gv))
(playz (tref (cast data userdata*) 1))
(quad (tref (cast data userdata*) 0)))
(cond ((= quad 1) (set! vplay1 #t)))
;;(printf "Preroll[%d]: %s\n" quad (gst_caps_to_string caps))
GST_FLOW_OK)))
(bind-func new_sample
(lambda (sink:GstAppSink* data:gpointer)
(let ((sample (gst_app_sink_pull_sample (cast sink i8*)))
(caps (gst_sample_get_caps sample))
(buffer (gst_sample_get_buffer sample))
(dat:i8* null)
(xsize:gsize 0)
(quad (tref (cast data userdata*) 0)))
;;(printf "Playing back on quad:%d\n" quad)
(set! dat inframedata)
(set! xsize (gst_buffer_extract buffer 0 dat datsize))
(gst_buffer_unref buffer)
; (gst_caps_unref caps)
;;(if (= xsize datsize) (printf "ok\n")(printf "not ok\n"))
GST_FLOW_OK)))
(bind-func eos
(lambda (sink:GstAppSink* data:gpointer)
(let ((quad (tref (cast data userdata*) 0))
(playz (tref (cast data userdata*) 1)))
;(cond ((= quad 1) (set! vplay1 #f) (set! sampledata1dirty #f)))
(printf "Finished Decoding[%d]!\n" quad)
void)))
(bind-func xtm_play
(lambda ()
(let (
(gstErr:GError* (halloc))
(pipeline (gst_parse_launch "v4l2src device=/dev/video1 ! videoscale ! videoflip method=5 ! appsink name=sink caps=video/x-raw,format=RGB,width=1024,height=768" gstErr))
(sink (gst_bin_get_by_name (cast pipeline GstBin*) "sink"))
(data:userdata* (halloc))
(callbacks:GstAppSinkCallbacks* (halloc))
(xsize:gsize 0)
(maxbuffers:guint 1)
)
(if (null? pipeline) (printf "problem: cant get pipeline\n") (printf "pipeline created...\n"))
(if (null? sink) (printf "problem: cant get sink\n") (printf "got sink from pipeline...\n"))
(gst_app_sink_set_max_buffers (cast sink i8*) maxbuffers)
(gst_app_sink_set_emit_signals (cast sink i8*) 1)
(gst_app_sink_set_drop (cast sink i8*) 1)
(tfill! callbacks
(get_native_fptr eos)
(get_native_fptr new_preroll)
(get_native_fptr new_sample))
(tset! data 0 1)
(tset! data 1 (cast pipeline GstElement*))
(gst_app_sink_set_callbacks (cast sink i8*) callbacks (cast data gpointer) null)
(let ((res (gst_element_set_state pipeline GST_STATE_PLAYING)))
(if (or (= res 1) (= res 2))
(begin (printf "Pipeline set to playing state\n")
#t)
(begin (printf "Unable to set the pipeline to playing state\n")
(gst_element_set_state pipeline GST_STATE_NULL)
(gst_object_unref (cast pipeline i8*))
#f)))
(cast sink i8*)
)))
(bind-func _glib_main_loop_call
(lambda ()
(g_main_context_iteration null 0)))
(bind-func glib_main_loop
(lambda ()
(_glib_main_loop_call)
(callback (+ (now) 1470) glib_main_loop))) ;;1470 makes 30 fps
($ (init_sample_data)
(init)
(glib_main_loop)
(xtm_play)
(printf "video input from v4l-device activated!\n")
)
Changing the sources of gst is unpractical. I could not find another way, and as my c skills are limted, I am not shure if the changes in buffer.* have unwanted side effects. For me it works fine.
It would be nice to add gstramer to the core libraries. Is that legally possible?