[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