Encode and Preview code
pchaurasia
pchaurasia at gameloreinc.com
Sun May 14 14:59:18 UTC 2017
Hi Folks,
I need to record a from my camera and concurrently, preview the video.
Following command line is working for me.
gst-launch-1.0 -vv nvcamerasrc fpsRange="30.0 30.0" !
'video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080,
format=(string)I420, framerate=(fraction)30/1' ! tee name=t ! queue leaky=1
! nvoverlaysink -e t. ! queue ! omxh265enc iframeinterval=24
bitrate=10000000 ! h265parse ! queue name=queenc ! matroskamux name=mux !
filesink location=/home/ubuntu/cameracapture2.mkv -e
I would like to convert this to code, so that I can extract and process the
frames being recorded.
Following is what I came up with. This code is not fully working - I see
image on preview screen and then everything freezes. The output encoded
video file is not generated. It seems that some queue/buffer is getting
choked. Please help with any potential issue in my code...
#include <gst/gst.h>
int main(int argc, char *argv[]) {
GstElement *pipeline, *source, *caps, *sink, *fsink;
GstBus *bus;
GstCaps *filtercaps;
GstElement *tee, *encoder_q,*encoder_qmux, *vq1, *vq2;
GstElement *encoder;
GstElement *parser;
GstElement *mux;
GstMessage *msg;
GstBin *recorder;
GstStateChangeReturn ret;
GstPad *srcpad,*sinkpad;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Create the elements */
source = gst_element_factory_make ("nvcamerasrc", "source");
sink = gst_element_factory_make ("nvoverlaysink", "sink");
tee = gst_element_factory_make ("tee", "videotee");
encoder_q = gst_element_factory_make ("queue", "encoderq");
encoder_qmux = gst_element_factory_make ("queue", "muxq");
vq1 = gst_element_factory_make ("queue", "q1");
vq2 = gst_element_factory_make ("queue", "q2");
encoder = gst_element_factory_make ("omxh265enc" , "h265encoder");
parser = gst_element_factory_make ("h265parse", "parser-h265");
mux = gst_element_factory_make ("matroskamux", "muxer");
fsink = gst_element_factory_make ("filesink", "destination");
recorder = GST_BIN(gst_bin_new("recording-bin"));
/* Create the empty pipeline */
pipeline = gst_pipeline_new ("test-pipeline");
if (!pipeline || !source || !sink || !tee || !encoder_q || !vq1 || !vq2||
!encoder || !parser || !mux || !fsink) {
g_printerr ("Not all elements could be created.\n");
return -1;
}
caps = gst_element_factory_make ("capsfilter", "filter");
g_assert (caps != NULL); /* should always exist */
filtercaps = gst_caps_from_string("video/x-raw(memory:NVMM),
width=(int)1920, height=(int)1080, format=(string)I420,
framerate=(fraction)30/1 ");
g_object_set (G_OBJECT (caps), "caps", filtercaps, NULL);
gst_caps_unref (filtercaps);
/* Modify the source's properties */
//g_object_set (source, "pattern", 0, NULL);
g_object_set (encoder, "iframeinterval" , 24, "bitrate" , 10000000, NULL);
g_object_set (mux, "name" , "mux", NULL);
g_object_set (fsink, "location", "/home/ubuntu/cameracapture2.mkv",
NULL);
g_object_set (encoder_qmux, "name", "queenc", NULL);
g_object_set (vq1, "leaky", 1, NULL);
/* Build recorder pipeline */
sinkpad = gst_element_get_static_pad(encoder_q,"sink");
GstPad *ghost = gst_ghost_pad_new("vsink", sinkpad);
if (NULL == ghost){
g_error("Unable to create ghostpad !\n");
}
gst_element_add_pad(GST_ELEMENT(recorder),ghost);
gst_object_unref (GST_OBJECT(sinkpad));
gst_element_link_many(encoder_q,encoder,parser,encoder_qmux,mux,
fsink,NULL);
/* Build the pipeline */
gst_bin_add_many (GST_BIN (pipeline), source, caps, tee, vq1, sink, vq2,
recorder, NULL);
if (gst_element_link_many (source,caps,tee, vq1, sink, NULL) != TRUE) {
g_printerr ("Elements could not be linked.\n");
gst_object_unref (pipeline);
return -1;
}
/* link the tee and queues */
srcpad = gst_element_get_request_pad(tee,"src_%u");
sinkpad = gst_element_get_static_pad(vq1,"sink");
gst_pad_link(srcpad,sinkpad);
gst_element_link(vq1,sink);
srcpad = gst_element_get_request_pad(tee,"src_%u");
sinkpad = gst_element_get_static_pad
(GST_ELEMENT(recorder),"vsink");
gst_pad_link(srcpad,sinkpad);
/* Start playing */
ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (pipeline);
return -1;
}
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Parse message */
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME
(msg->src), err->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info :
"none");
g_clear_error (&err);
g_free (debug_info);
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.\n");
break;
default:
/* We should not reach here because we only asked for ERRORs and EOS
*/
g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}
/* Free resources */
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Encode-and-Preview-code-tp4682997.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
More information about the gstreamer-devel
mailing list