Trying to capture from v4l2src and alsasrc to a new .mp4 file every N seconds.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Trying to capture from v4l2src and alsasrc to a new .mp4 file every N seconds.

startoftext
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-






------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel