Hi All,
I am trying to create a pipeline in C++ with appsrc as a source and filesink as a sink element. For simplicity I am creating a buffer with alternating black and white frames and pushing it into appsrc. My goal is to create an mp4 video as output. The program is creating the file that grows in size with time of execution. But when I open it to read, it doesn't open up. Could someone please point me in the right direction to solve the problem? Thanks in advance. Best, Manoj Here goes the code: #include <gst/gst.h> #include <gst/app/gstappsrc.h> #include <iostream> static GMainLoop *loop; GstElement *pipeline, *appsrc, *filter1, *conv, *filter2, *encoder, *parser, *muxer, *filesink; GstCaps *filter1_caps; GstCaps *filter2_caps; GstBus *bus; guint bus_watch_id; static void cb_need_data(GstElement *appsrc, guint unused_size, gpointer user_data) { static gboolean white = FALSE; static GstClockTime timestamp = 0; GstBuffer *buffer; guint size; GstFlowReturn ret; size = 640 * 480 * 3; buffer = gst_buffer_new_allocate(NULL, size, NULL); /* this makes the image black/white */ gst_buffer_memset(buffer, 0, white ? 0xff : 0x0, size); white = !white; GST_BUFFER_PTS (buffer) = timestamp; GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 2); timestamp += GST_BUFFER_DURATION(buffer); g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret); gst_buffer_unref(buffer); if (ret != GST_FLOW_OK) { /* something wrong, send EOS event and stop pushing */ gst_element_send_event(pipeline, gst_event_new_eos()); g_main_loop_quit(loop); } } static gboolean my_bus_callback(GstBus *bus, GstMessage *message, gpointer data) { g_print("Got %s message\n", GST_MESSAGE_TYPE_NAME(message)); switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_ERROR: { GError *err; gchar *debug; gst_message_parse_error(message, &err, &debug); g_printerr("ERROR from element %s: %s\n", GST_OBJECT_NAME(message->src), err->message); g_printerr("Debugging info: %s\n", (debug) ? debug : "none"); g_error_free(err); g_free(debug); std::cin.get(); g_main_loop_quit(loop); break; } case GST_MESSAGE_EOS: /* end-of-stream */ std::cin.get(); g_main_loop_quit(loop); break; default: g_print("Debug raw message: %s\n", message); break; } return TRUE; } gint main(gint argc, gchar *argv[]) { /* init GStreamer */ gst_init(&argc, &argv); gst_debug_set_default_threshold(GST_LEVEL_INFO); loop = g_main_loop_new(NULL, FALSE); /* setup pipeline */ pipeline = gst_pipeline_new("pipeline"); appsrc = gst_element_factory_make("appsrc", "source"); filter1 = gst_element_factory_make ("capsfilter", "filter1"); conv = gst_element_factory_make("autovideoconvert", "conv"); encoder = gst_element_factory_make("x264enc", "encoder"); filter2 = gst_element_factory_make ("capsfilter", "filter2"); parser = gst_element_factory_make ("h264parse", "parser"); muxer = gst_element_factory_make("mp4mux", "muxer"); filesink = gst_element_factory_make("filesink", "filesink"); /* setup appsrc */ g_object_set(G_OBJECT(appsrc), "stream-type", GST_APP_STREAM_TYPE_STREAM, "format", GST_FORMAT_TIME, NULL); g_signal_connect(appsrc, "need-data", G_CALLBACK (cb_need_data), NULL); /* setup */ g_object_set(G_OBJECT(appsrc), "caps", gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "RGB", "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 480, "framerate", GST_TYPE_FRACTION, 0, 1, NULL), NULL); filter1_caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "RGB", "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 480, NULL); filter2_caps = gst_caps_new_simple ("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL); g_object_set (G_OBJECT (filter1), "caps", filter1_caps, NULL); g_object_set (G_OBJECT (filter2), "caps", filter2_caps, NULL); gst_caps_unref (filter1_caps); gst_caps_unref (filter2_caps); g_object_set(G_OBJECT(filesink), "location", "C:\\CppWorkspace\\GstreamerApps\\testout.mp4", NULL); gst_bin_add_many(GST_BIN(pipeline), appsrc, filter1, conv, encoder, filter2, parser, muxer, filesink, NULL); gst_element_link_many(appsrc, filter1, conv, encoder, filter2, parser, muxer, filesink, NULL); /* adds a watch for new message on our pipeline's message bus to * the default GLib main context, which is the main context that our * GLib main loop is attached to below */ bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); bus_watch_id = gst_bus_add_watch(bus, my_bus_callback, NULL); std::cout << bus_watch_id; /* play */ gst_element_set_state(pipeline, GST_STATE_PLAYING); g_main_loop_run(loop); /* clean up */ gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(pipeline)); gst_object_unref(bus); g_main_loop_unref(loop); return 0; } _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |