GStreamer pipelines

Hi guys. I’ve been having some issues with encoding to Vorbis under Linux. I have the following code:

  
void VideoRecorder::startRecordPipeline2(){  
  
    string command = ("v4l2src ! video/x-raw-yuv,width=640,height=480,framerate=15/1 ! tee name=t_vid \  
    ! queue ! ffmpegcolorspace ! edgetv ! ffmpegcolorspace ! appsink name=internalsink t_vid. ! queue ! \  
    videorate ! ffmpegcolorspace ! edgetv ! ffmpegcolorspace ! video/x-raw-yuv,framerate=15/1 ! \  
    theoraenc ! queue ! mux. alsasrc device=hw:1,0 ! audio/x-raw-int,rate=22050,channels=1,width=16 \  
    ! queue ! audioconvert ! queue ! vorbisenc ! queue ! mux. oggmux name=mux ! filesink location=")  
    + ofToDataPath("test.ogv");  
  
    cout << command << endl;  
  
gchar* pipeline_string =  
		g_strdup( command.c_str() ); // caps=video/x-raw-rgb  
  
	GError * error = NULL;  
	GstElement* gstPipeline = gst_parse_launch (pipeline_string, &error);  
	if (!gstPipeline || error){  
        cout << "Error in Pipeline Creation - " << error->message <<endl;  
        return;  
	}  
  
	GstElement* gstSink = gst_bin_get_by_name(GST_BIN(gstPipeline),"internalsink");  
	if (!gstSink){  
        cout << "Error in retrieving AppSink"  <<endl;  
        return;  
	}  
  
    gst_base_sink_set_sync(GST_BASE_SINK(gstSink), true);  
	// gst_base_sink_set_sync(GST_BASE_SINK(gstSink), true);  
  
    GstAppSinkCallbacks gstCallbacks;  
    gstCallbacks.new_preroll = &on_new_preroll_from_source_record;  
    gstCallbacks.new_buffer = &on_new_buffer_from_source_record;  
  
    gst_app_sink_set_callbacks(GST_APP_SINK(gstSink), &gstCallbacks, &gstDataRecord, NULL);  
  
    if(gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_PAUSED) ==  
	   GST_STATE_CHANGE_FAILURE) {  
		cout << "GStreamer: unable to set record pipeline to paused" << endl;  
		return;  
	}  
    gst_element_set_state (gstPipeline, GST_STATE_PLAYING);  
}  
  
  
void VideoRecorder::stopRecordPipeline(){  
  
   // gst_element_send_event (recordPipeline,gst_event_new_eos ());  
  
    gst_element_set_state (recordPipeline, GST_STATE_PAUSED);  
    gst_element_set_state (recordPipeline, GST_STATE_READY);  
    gst_element_set_state (recordPipeline, GST_STATE_NULL);  
    g_print ("Deleting record pipeline\n");  
    gst_object_unref (GST_OBJECT (recordPipeline));  
}  

This results in the following errors:

  
*** glibc detected *** ./Animation10Client_debug: malloc(): memory corruption: 0xb2c185e8 ***  
======= Backtrace: =========  
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x10ec591]  
/lib/tls/i686/cmov/libc.so.6(+0x6e395)[0x10ef395]  
/lib/tls/i686/cmov/libc.so.6(__libc_calloc+0xab)[0x10f070b]  
/usr/lib/libvorbisenc.so.2(+0x8943)[0x60a8943]  
/usr/lib/libvorbisenc.so.2(vorbis_encode_setup_init+0x12b)[0x60a8d6b]  
/usr/lib/gstreamer-0.10/libgstvorbis.so(+0x96fa)[0x6ac26fa]  
/usr/lib/gstreamer-0.10/libgstvorbis.so(+0x99c1)[0x6ac29c1]  
/usr/lib/libgstreamer-0.10.so.0(gst_pad_set_caps+0x284)[0x1d7e314]  
/usr/lib/libgstreamer-0.10.so.0(+0x51c34)[0x1d7ec34]  
/usr/lib/libgstreamer-0.10.so.0(+0x51f1c)[0x1d7ef1c]  
/usr/lib/libgstreamer-0.10.so.0(+0x52864)[0x1d7f864]  
/usr/lib/libgstbase-0.10.so.0(+0x2875a)[0x41a375a]  
/usr/lib/libgstreamer-0.10.so.0(+0x51e05)[0x1d7ee05]  
/usr/lib/libgstreamer-0.10.so.0(+0x52864)[0x1d7f864]  
/usr/lib/libgstbase-0.10.so.0(+0x2145a)[0x419c45a]  
/usr/lib/libgstreamer-0.10.so.0(+0x7dd6b)[0x1daad6b]  
/usr/lib/libgstreamer-0.10.so.0(+0x7f377)[0x1dac377]  
/lib/libglib-2.0.so.0(+0x67d0c)[0x4bd1d0c]  
/lib/libglib-2.0.so.0(+0x65def)[0x4bcfdef]  
/lib/tls/i686/cmov/libpthread.so.0(+0x596e)[0x8d9096e]  
/lib/tls/i686/cmov/libc.so.6(clone+0x5e)[0x114ea4e]  
======= Memory map: ========  
00110000-00114000 r-xp 00000000 08:05 1047673    /usr/lib/libXxf86vm.so.1.0.0  
00114000-00115000 r--p 00003000 08:05 1047673    /usr/lib/libXxf86vm.so.1.0.0  
00115000-00116000 rw-p 00004000 08:05 1047673    /usr/lib/libXxf86vm.so.1.0.0  
00116000-00119000 r-xp 00000000 08:05 1052576    /usr/lib/gstreamer-0.10/libgstaasink.so  
00119000-0011a000 ---p 00003000 08:05 1052576    /usr/lib/gstreamer-0.10/libgstaasink.so  
0011a000-0011b000 r--p 00003000 08:05 1052576    /usr/lib/gstreamer-0.10/libgstaasink.so  
0011b000-0011c000 rw-p 00004000 08:05 1052576    /usr/lib/gstreamer-0.10/libgstaasink.so  
0011c000-0011f000 r-xp 00000000 08:05 1052578    /usr/lib/gstreamer-0.10/libgstadpcmdec.so  
0011f000-00120000 r--p 00002000 08:05 1052578    /usr/lib/gstreamer-0.10/libgstadpcmdec.so  
00120000-00121000 rw-p 00003000 08:05 1052578    /usr/lib/gstreamer-0.10/libgstadpcmdec.so  
00121000-00124000 r-xp 00000000 08:05 1052579    /usr/lib/gstreamer-0.10/libgstadpcmenc.so  
00124000-00125000 r--p 00002000 08:05 1052579    /usr/lib/gstreamer-0.10/libgstadpcmenc.so  
00125000-00126000 rw-p 00003000 08:05 1052579    /usr/lib/gstreamer-0.10/libgstadpcmenc.so  
00126000-00131000 r-xp 00000000 08:05 1052580    /usr/lib/gstreamer-0.10/libgstaiff.so  
00131000-00132000 r--p 0000a000 08:05 1052580    /usr/lib/gstreamer-0.10/libgstaiff.so  
00132000-00133000 rw-p 0000b000 08:05 1052580    /usr/lib/gstreamer-0.10/libgstaiff.so  
00133000-00137000 r-xp 00000000 08:05 1052581    /usr/lib/gstreamer-0.10/libgstalaw.so  
00137000-00138000 r--p 00003000 08:05 1052581    /usr/lib/gstreamer-0.10/libgstalaw.so  
00138000-00139000 rw-p 00004000 08:05 1052581    /usr/lib/gstreamer-0.10/libgstalaw.so  
00139000-00154000 r-xp 00000000 08:05 264664     /lib/ld-2.11.1.so  
00154000-00155000 r--p 0001a000 08:05 264664     /lib/ld-2.11.1.so  
00155000-00156000 rw-p 0001b000 08:05 264664     /lib/ld-2.11.1.so  
00156000-001b0000 r-xp 00000000 08:05 1047033    /usr/lib/mesa/libGL.so.1.2  
001b0000-001b5000 r--p 00059000 08:05 1047033    /usr/lib/mesa/libGL.so.1.2  
001b5000-001ba000 rwxp 0005e000 08:05 1047033    /usr/lib/mesa/libGL.so.1.2  
001ba000-001bb000 rwxp 00000000 00:00 0   
001bb000-0027e000 r-xp 00000000 08:05 1047701    /usr/lib/libasound.so.2.0.0  
0027e000-00282000 r--p 000c2000 08:05 1047701    /usr/lib/libasound.so.2.0.0  
00282000-00283000 rw-p 000c6000 08:05 1047701    /usr/lib/libasound.so.2.0.0  
00283000-00288000 r-xp 00000000 08:05 1052585    /usr/lib/gstreamer-0.10/libgstalsaspdif.so  
00288000-00289000 r--p 00004000 08:05 1052585    /usr/lib/gstreamer-0.10/libgstalsaspdif.so  
00289000-0028a000 rw-p 00005000 08:05 1052585    /usr/lib/gstreamer-0.10/libgstalsaspdif.so  
0028a000-0028d000 r-xp 00000000 08:05 1052589    /usr/lib/gstreamer-0.10/libgstapetag.so  
0028d000-0028e000 r--p 00002000 08:05 1052589    /usr/lib/gstreamer-0.10/libgstapetag.so  
0028e000-0028f000 rw-p 00003000 08:05 1052589    /usr/lib/gstreamer-0.10/libgstapetag.so  
0028f000-00290000 r-xp 00000000 08:05 1052591    /usr/lib/gstreamer-0.10/libgstapp.so  
00290000-00291000 r--p 00000000 08:05 1052591    /usr/lib/gstreamer-0.10/libgstapp.so  
00291000-00292000 rw-p 00001000 08:05 1052591    /usr/lib/gstreamer-0.10/libgstapp.so  
00292000-002a3000 r-xp 00000000 08:05 1052593    /usr/lib/gstreamer-0.10/libgstasfmux.so  
002a3000-002a4000 r--p 00010000 08:05 1052593    /usr/lib/gstreamer-0.10/libgstasfmux.so  
002a4000-002a5000 rw-p 00011000 08:05 1052593    /usr/lib/gstreamer-0.10/libgstasfmux.so  
002a6000-002a7000 r-xp 00000000 00:00 0          [vdso]  
002a7000-002c5000 r-xp 00000000 08:05 1052592    /usr/lib/gstreamer-0.10/libgstasf.so  
002c5000-002c6000 ---p 0001e000 08:05 1052592    /usr/lib/gstreamer-0.10/libgstasf.so  
002c6000-002c7000 r--p 0001e000 08:05 1052592    /usr/lib/gstreamer-0.10/libgstasf.so  
002c7000-002c8000 rw-p 0001f000 08:05 1052592    /usr/lib/gstreamer-0.10/libgstasf.so  
002c8000-002d2000 r-xp 00000000 08:05 1052594    /usr/lib/gstreamer-0.10/libgstassrender.so  
002d2000-002d3000 r--p 00009000 08:05 1052594    /usr/lib/gstreamer-0.10/libgstassrender.so  
002d3000-002d4000 rw-p 0000a000 08:05 1052594    /usr/lib/gstreamer-0.10/libgstassrender.so  
002d4000-002e2000 r-xp 00000000 08:05 1052595    /usr/lib/gstreamer-0.10/libgstaudioconvert.so  
002e2000-002e3000 r--p 0000d000 08:05 1052595    /usr/lib/gstreamer-0.10/libgstaudioconvert.so  
002e3000-002e4000 rw-p 0000e000 08:05 1052595    /usr/lib/gstreamer-0.10/libgstaudioconvert.so  
002e4000-002f7000 r-xp 00000000 08:05 1052597    /usr/lib/gstreamer-0.10/libgstaudioparsersbad.so  
002f7000-002f8000 r--p 00012000 08:05 1052597    /usr/lib/gstreamer-0.10/libgstaudioparsersbad.so  
002f8000-002f9000 rw-p 00013000 08:05 1052597    /usr/lib/gstreamer-0.10/libgstaudioparsersbad.so  
002f9000-00306000 r-xp 00000000 08:05 1052599    /usr/lib/gstreamer-0.10/libgstaudioresample.soAborted  
  

Now if I run the command line with gst-launch, all is perfectly well. Im wondering what the difference could be here? What is gst-launch doing differently from the C++ code I’ve written? Im think different libraries or something but I cant be sure.

the gstUtils class uses several flags internally, that if not set correctly can make your extended class crash. is better to use the setPipeline or in your case setPipelineWithSink and pass the command by parameter. that way it will set all the needed flags correctly.

For what i see you’re trying to pass the stream your encoding to OF at the same time. i haven’t tried that case, so try first just with the encoding to see if you can get it to work. i will give this a look and see how can you set up a pipeline that has two sinks.

I should point out that this class is separate and doesn’t use the gstUtils class. I decided to write my own precisely because I need two sinks for this to work. Outside of C it works fine. gst-launch will do it’s thing and it sends the correct data.

I would further like to mention that using:

ffenc_mpeg4
aacenc
avimux

in place of vorbis and theora and oggmux works fine (though the quality is worse). Ergo, I can only assume that something within the vorbis encoder library is broken when it’s linked from a C context. Im not doing anything with the buffers from the appsink at the moment.

Im wondering if this is actually a genuine bug

yes, i’ve had some problems also with some muxers, for what i remember oggmux used to work but others like mp4mux or qtmux doesn’t work even from gst-launch.

i’ve got the best quality with x264enc ! avimux for h264 or y4menc ! avimux for no compression

I’m about to try the 10.29 release of gstreamer to see if that makes a difference, otherwise I’m going to have to do compression as a separate thread outside of Openframeworks to do the compression that way (possibly by calling a script to compress the video).

No joy at all.

I’ve been fighting with Quicktime… no joy for a week. fighting with GStreamer… no joy for 3 days. Im getting behind and this is not good. All I want is the ability to create videos with a chosen filter whilst being able to preview them at the same time. Gstreamer can do this BUT NOT INSIDE OF! That is unbelievable really. Something crazy is going on between gst-launch and my c code; they aint doing the same thing. Its extremely frustrating as my pipeline IS CORRECT!

Bad day.

someone, found a problem with OF and gstreamer some days ago. the thing is if you link fmod, some codecs make the app crash. perhaps that’s what’s happening. try removing all dependencies with fmod. you need to remove ofSoundPlayer.h/.cpp from your project. remove the include in ofmain and comment line 56 in ofAppRunner.cpp:

  
ofSoundPlayer::closeFmod();  

also if that doesn’t work, can you try debugging your app and see in what line is crashing?

I was having a bad day, apologies for the rant.

Thanks for the help Arturo. Sadly, that fmod trick didnt work as planned. I’ve made a small test program in C that mimics what I’m trying to do:

  
#include <gst/gst.h>  
#include <stdbool.h>  
  
static GMainLoop *loop;  
  
static gboolean bus_call(GstBus *bus, GstMessage *msg, void *user_data)  
{  
	switch (GST_MESSAGE_TYPE(msg)) {  
	case GST_MESSAGE_EOS:  
		{  
			g_message("End-of-stream");  
			g_main_loop_quit(loop);  
			break;  
		}  
	case GST_MESSAGE_ERROR:  
		{  
			gchar *debug;  
			GError *err;  
  
			gst_message_parse_error(msg, &err, &debug);  
			g_free(debug);  
  
			g_error("%s", err->message);  
			g_error_free(err);  
  
			g_main_loop_quit(loop);  
			break;  
		}  
	default:  
		break;  
	}  
  
	return true;  
}  
  
static void runpipeline()  
{  
  
	 const char* command = "v4l2src ! video/x-raw-yuv,width=640,height=480,framerate=15/1 ! tee name=t_vid \  
    ! queue ! ffmpegcolorspace ! edgetv ! ffmpegcolorspace ! appsink name=internalsink t_vid. ! queue ! \  
    videorate ! ffmpegcolorspace ! edgetv ! ffmpegcolorspace ! video/x-raw-yuv,framerate=15/1 ! \  
    theoraenc ! queue ! mux. alsasrc device=hw:1,0 ! audio/x-raw-int,rate=22050,channels=1,width=16 \  
    ! queue ! audioconvert ! queue ! vorbisenc ! queue ! mux. oggmux name=mux ! filesink location=test.ogv";  
  
    
	gchar* pipeline_string = g_strdup(command); // caps=video/x-raw-rgb  
  
	GError * error = NULL;  
	GstElement* gstPipeline = gst_parse_launch (pipeline_string, &error);  
	if (!gstPipeline || error){  
		g_print("Error in Pipeline creation\n");  
        return;  
	}  
  
	GstElement* gstSink = gst_bin_get_by_name(GST_BIN(gstPipeline),"internalsink");  
	if (!gstSink){  
       		g_print("Error in Pipeline creation\n");  
        return;  
	}  
  
   
	GstBus *bus;  
  
	loop = g_main_loop_new(NULL, FALSE);  
  
  
	bus = gst_pipeline_get_bus(GST_PIPELINE(gstPipeline));  
	gst_bus_add_watch(bus, bus_call, NULL);  
	gst_object_unref(bus);  
  
	gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_PLAYING);  
  
	g_main_loop_run(loop);  
  
	gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_NULL);  
	gst_object_unref(GST_OBJECT(gstPipeline	));  
}  
  
int main(int argc, char *argv[])  
{  
	gst_init(&argc, &argv);  
	runpipeline();  
	return 0;  
}  

Of course, this is using the main loop and not doing some kind of asynchronous interrupt like the gstutils code does. Im wondering if thats it? Im back with the stock install of gstreamer (10.28-ubuntu) as oppose to bleeding edge. The crashes have returned. I think i must be trampling over some memory I shouldn’t be and that is causing issues.

I think a rewrite of my own recording class is probably in order; get things simplified, take out the gstutils for now and see what happens. Since the exception is caught within the vorbis library I cant get to it without some serious environment changes and boiler plating. Will think on and see what the deal is.

Ok I think I’ve found it. Turns out that the OF project was still pulling in libmodex according to my memory dump. I found the offending line and we might very well be there. Managing to get some video out now. Will keep testing to make sure. Thanks a lot for your help man, you are a lifesaver!

hey, cool that it’s working, i want to take a look at that idea of having two different sinks so you can do things like encoding or streaming a file or camera stream while previewing it in OF. it shouldn’t be too difficult to add it to setPipeline.