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 -eI 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; } |
Free forum by Nabble | Edit this page |