[gst-devel] Trying to capture from v4l2src and alsasrc to a new .mp4 file every N seconds.

James Pearson startoftext at gmail.com
Sat Aug 22 04:25:55 CEST 2009


I am very desperate for help. I am trying to capture live video from  
v4l2src and alsasrc, which I can do with no problems. The problem is  
that I want a new file every N seconds. I keep reading and trying to  
do it but failing epically. I feel like I am so close but I am missing  
something. Its how to change out the parts of the pipeline that need  
to be changed and still have an eos even occur so that the .mp4 file  
does not end up missing things. As you can see in my source I have  
tried many things by all the commented lines in that area. In its  
current state the code below will sorta work but its has corrupt mp4  
headers and the files dont play correctly if at all most of the time.

I dont mean for this to be a here is my broken code will you fix it  
for me but I am not sure how else to ask for help. If you need any  
detail or want some explanation feel free to ask. = - (

/********************************************************************
vidcap.c
James Pearson
********************************************************************/
#include <gst/gst.h>
// I pasted the vidcap_hf.c file below
#include "vidcap_hf.h"

int main(int argc, char * argv[]){
	static GMainLoop *loop;
	loop = g_main_loop_new (NULL, FALSE);
	gchar outfilepath[25] = "outfile0.mp4";
	gchar *input_device = "/dev/video0";
	
	unsigned int i=0;
	
	GstElement *pipeline;
	GstElement *v4l2src;
	GstElement *alsasrc;
	GstElement *audio_convert;
	GstElement *ffmpegcolorspace;
	GstElement *recBin;
	
	GstElement *aqueue;
	GstElement *vqueue;
	
	GstCaps *caps;
	
	// Init gstreamer
	gst_init(NULL, NULL);

	//Create GST elements
	pipeline = gst_pipeline_new(NULL);
	v4l2src = gst_element_factory_make("v4l2src", "src0");
	alsasrc = gst_element_factory_make("alsasrc", "alsasrc0");
	//lame = gst_element_factory_make("lame", "lame0");
	audio_convert = gst_element_factory_make("audioconvert",  
"audioconvert0");
	
	ffmpegcolorspace = gst_element_factory_make("ffmpegcolorspace",  
"ffmpegcolorspace");
	//ffenc_mpeg4 = gst_element_factory_make ("ffenc_mpeg4", "ffenc0");
	//ffmux_mp4 = gst_element_factory_make("ffmux_mp4", "mux0");
	//filesink = gst_element_factory_make("filesink", "filesink0");
	
	aqueue = gst_element_factory_make("queue", NULL);
	vqueue = gst_element_factory_make("queue", NULL);
	
	// Creat some caps stuff
	caps = gst_caps_new_simple ("video/x-raw-yuv","width", G_TYPE_INT,  
320, "height", G_TYPE_INT, 240, "framerate", GST_TYPE_FRACTION, 30, 1,  
NULL);
	
	// TODO Check GST elements created ok here
	
	// Set some paramaters for the GstElements
	g_object_set( G_OBJECT(v4l2src), "device", input_device, NULL);
	
	// Add elements to pipeline
	gst_bin_add_many ( GST_BIN(pipeline), v4l2src, alsasrc,  
audio_convert, ffmpegcolorspace, vqueue, aqueue, NULL);
	
	
	// Link some elements
	if ( !gst_element_link_filtered( v4l2src, ffmpegcolorspace, caps) ){
		g_warning("Failed to link elements v4l2src and ffmpegcolorspace");
	}
	if ( !gst_element_link(ffmpegcolorspace,vqueue) ){
		g_warning("Failed to link elements ffmpegcolorspace and vqueue");
	}
	if ( !gst_element_link_many(alsasrc,audio_convert,aqueue,NULL) ){
		g_warning("Failed to link elements audio elements");
	}
	
	//g_main_loop_run(loop);
	for(i=0 ; i < 3 ; ++i){
		// make a new record bin
		outfilepath[7] = i+48;
		recBin = newRecordBin(outfilepath);
		
		if(recBin == NULL){
			printf("Error creating new recBin\n");
		}
		
		// add record bin to pipeline
		gst_bin_add(GST_BIN(pipeline), recBin);
		
		// link elements
		if( !gst_element_link(vqueue,recBin) ){
			g_warning("Failed to link vqueue with recBin");
		}
		if( !gst_element_link(aqueue,recBin) ){
			g_warning("Failed to link aqueue with recBin");
		}
		/*
		if( !gst_element_link_pads(vqueue,"src",recBin,"vsink") ){
			g_warning("Failed to link vqueue with recBin");
		}
		if( !gst_element_link_pads(aqueue,"src",recBin,"asink") ){
			g_warning("Failed to link aqueue with recBin");
		}
		*/
		/*
		if( !gst_element_link_many(vqueue,recBin,NULL) ){
			g_warning("Failed to link queues with recBin");
		}*/
		
		// Play pipeline
		gst_element_set_state(pipeline, GST_STATE_PAUSED);
		gst_element_set_state(pipeline, GST_STATE_PLAYING);
		
		printf("Main thread going to sleep\n");
		sleep(15);
		
		/*
		gst_element_unlink(vqueue,recBin);
		gst_element_unlink(aqueue,recBin);
		// possible leak here
		gst_pad_send_event( gst_element_get_static_pad(recBin, "asink"),  
gst_event_new_eos());
		gst_pad_send_event( gst_element_get_static_pad(recBin, "vsink"),  
gst_event_new_eos());
		//gst_element_send_event( recBin, gst_event_new_eos());
		sleep(1);
		gst_bin_remove(GST_BIN(pipeline), recBin);
		gst_element_set_state(recBin, GST_STATE_NULL);
		*/
		
		//gst_bin_remove(GST_BIN(pipeline), recBin);
		// send eos so mp4 muxer can finish
		//gst_element_set_state( pipeline , GST_STATE_READY);
		//gst_element_send_event( pipeline, gst_event_new_eos());
		//sleep(1);
		//gst_element_set_state(recBin, GST_STATE_READY);
		//gst_bin_remove(GST_BIN(pipeline), recBin);
		
		
		gst_element_set_state(pipeline, GST_STATE_READY);
		gst_bin_remove(GST_BIN(pipeline), recBin);
		gst_element_set_state(recBin, GST_STATE_NULL);
		gst_object_unref(recBin);
		
		
	}
	
	
	sleep(1);
	//gst_element_set_state( pipeline , GST_STATE_NULL);
	
	
	gst_object_unref(pipeline);
	gst_caps_unref(caps);
	
	
	return(0);
}

/********************************************************************
vidcap_hf.c
James Pearson
********************************************************************/
#include"vidcap_hf.h"

GstElement* newRecordBin(char *filename){
	
	GstElement *recBin = gst_bin_new(NULL);
	GstElement *encV = gst_element_factory_make("ffenc_mpeg4",NULL);
	GstElement *encA = gst_element_factory_make("lame",NULL);
	GstElement *mux = gst_element_factory_make("ffmux_mp4",NULL);
	GstElement *sink = gst_element_factory_make("filesink",NULL);
	
	
	
	g_object_set( G_OBJECT(sink), "location", filename, NULL);
	
	// Add elements to the bin
	gst_bin_add_many(GST_BIN(recBin),encV,encA,mux,sink,NULL);
	
	
	
	GstPad *vPad = gst_element_get_static_pad (encV, "sink");
	GstPad *aPad = gst_element_get_static_pad (encA, "sink");
	
	// Add ghost pads to sink
	gst_element_add_pad (recBin, gst_ghost_pad_new ("asink", aPad));
	gst_element_add_pad (recBin, gst_ghost_pad_new ("vsink", vPad));
	
	// unref the pads, this was what the docs say to do, I think the lib  
copies them
	gst_object_unref( GST_OBJECT(aPad) );
	gst_object_unref( GST_OBJECT(vPad) );
	
	// Connect everything togather
	// ARGH for some reason when i link them at once there is an error...
	/*if( !gst_element_link_many(encV,encA,mux,sink,NULL) ){
		g_warning("Error linking elements in newRecordBin");
	}*/
	if( !gst_element_link(encV,mux) ){
		g_warning("Error linking encV mux in newRecordBin");
	}
	if( !gst_element_link(encA,mux) ){
		g_warning("Error linking encA mux in newRecordBin");
	}
	if( !gst_element_link(mux,sink) ){
		g_warning("Error linking mux filesink in newRecordBin");
	}
	
	return(recBin);
}


-James Pearson-





-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20090821/e8562fde/attachment.htm>


More information about the gstreamer-devel mailing list