3 * Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
23 gcc -Wall `pkg-config --cflags --libs gstreamer-0.10` gst-camerabin-test.c -o gst-camerabin-test
26 ./gst-camerabin-test --image-width=2048 --image-height=1536 --image-enc=dspjpegenc
27 ./gst-camerabin-test --mode=1 --capture-time=10 --image-width=848 --image-height=480 --view-framerate-num=2825 \
28 --view-framerate-den=100 --audio-src=pulsesrc --audio-enc=nokiaaacenc --video-enc=dspmp4venc \
29 --video-mux=mp4mux --src-colorspace=UYVY
31 ./gst-camerabin-test --help
33 gst-camerabin-test [OPTION...]
35 camerabin command line test application
38 -h, --help Show help options
39 --help-all Show all help options
40 --help-gst Show GStreamer Options
43 --ev-compensation EV compensation (-2.5..2.5, default = 0)
44 --aperture Aperture (size of lens opening, default = 0 (auto))
45 --flash-mode Flash mode (default = 0 (auto))
46 --scene-mode Scene mode (default = 6 (auto))
47 --exposure Exposure (default = 0 (auto))
48 --iso-speed ISO speed (default = 0 (auto))
49 --white-balance-mode White balance mode (default = 0 (auto))
50 --colour-tone-mode Colour tone mode (default = 0 (auto))
51 --directory Directory for capture file(s) (default is current directory)
52 --mode Capture mode (default = 0 (image), 1 = video)
53 --capture-time Time to capture video in seconds (default = 10)
54 --capture-total Total number of captures to be done
55 --flags Flags for camerabin, (default = 0x9)
56 --mute Mute audio (default = 0 (no))
57 --zoom Zoom (100 = 1x (default), 200 = 2x etc.)
58 --audio-src Audio source used in video recording
59 --audio-bitrate Audio bitrate (default 128000)
60 --audio-samplerate Audio samplerate (default 48000)
61 --audio-channels Audio channels (default 1)
62 --video-src Video source used in still capture and video recording
63 --audio-enc Audio encoder used in video recording
64 --video-enc Video encoder used in video recording
65 --image-enc Image encoder used in still capture
66 --image-pp Image post-processing element
67 --video-mux Muxer used in video recording
68 --viewfinder-sink Viewfinder sink (default = fakesink)
69 --image-width Width for image capture
70 --image-height Height for image capture
71 --view-framerate-num Framerate numerator for viewfinder
72 --view-framerate-den Framerate denominator for viewfinder
73 --src-colorspace Colorspace format for videosource (e.g. YUY2, UYVY)
74 --preview-caps Preview caps (e.g. video/x-raw-rgb,width=320,height=240)
75 --video-source-filter Video filter to process all frames from video source
76 --viewfinder-filter Filter to process all frames going to viewfinder sink
88 #include <gst/interfaces/xoverlay.h>
95 #include <glib/gstdio.h>
98 #include <X11/Xatom.h>
102 GST_DEBUG_CATEGORY_STATIC (camerabin_test);
103 #define GST_CAT_DEFAULT camerabin_test
105 typedef struct _ResultType
116 static GstElement *camera_bin = NULL;
117 static GMainLoop *loop = NULL;
119 /* commandline options */
120 static gchar *audiosrc_name = NULL;
121 static gchar *videosrc_name = NULL;
122 static gchar *audioenc_name = NULL;
123 static gchar *videoenc_name = NULL;
124 static gchar *imageenc_name = NULL;
125 static gchar *imagepp_name = NULL;
126 static gchar *videomux_name = NULL;
127 static gchar *vfsink_name = NULL;
128 static gchar *src_csp = NULL;
129 static gchar *src_format = NULL;
130 static gint image_width = 1280;
131 static gint image_height = 720;
132 static gint view_framerate_num = 2825;
133 static gint view_framerate_den = 100;
135 /* photography interface command line options */
136 static gfloat ev_compensation = 0.0;
137 static gint aperture = 0;
138 static gint flash_mode = 0;
139 static gint scene_mode = 6;
140 static gint64 exposure = 0;
141 static gint iso_speed = 0;
142 static gint wb_mode = 0;
143 static gint color_mode = 0;
144 static gint mode = 1;
145 static gint flags = 0x4f;
146 static gint mute = 0;
147 static gint zoom = 100;
149 static gint capture_time = 10;
150 static gint capture_count = 0;
151 static gint capture_total = 1;
153 /* audio capsfilter options */
154 static gint audio_bitrate = 128000;
155 static gint audio_samplerate = 48000;
156 static gint audio_channels = 1;
158 static gchar *video_src_filter = NULL;
159 static gchar *viewfinder_filter = NULL;
161 static int x_width = 320;
162 static int x_height = 240;
164 /* test configuration for common callbacks */
165 static GString *filename = NULL;
167 static gchar *preview_caps_name = NULL;
169 /* X window variables */
170 static Display *display = NULL;
171 static Window window = 0;
176 static gboolean run_pipeline (gpointer user_data);
177 static void set_metadata (GstElement * camera);
180 create_host_window (void)
182 unsigned long valuemask;
183 XSetWindowAttributes attributes;
185 display = XOpenDisplay (NULL);
188 XCreateSimpleWindow (display, DefaultRootWindow (display), 0, 0,
189 x_width, x_height, 0, 0, 0);
191 valuemask = CWOverrideRedirect;
192 attributes.override_redirect = True;
193 XChangeWindowAttributes (display, window, valuemask, &attributes);
194 XSetWindowBackgroundPixmap (display, window, None);
195 XMapRaised (display, window);
196 XSync (display, FALSE);
198 GST_DEBUG ("could not create X window!");
201 GST_DEBUG ("could not open display!");
206 img_capture_done (GstElement * camera, const gchar * fname, gpointer user_data)
208 gboolean ret = FALSE;
210 GST_DEBUG ("image done: %s", fname);
211 if (capture_count < capture_total) {
212 g_idle_add ((GSourceFunc) run_pipeline, NULL);
214 g_main_loop_quit (loop);
219 static GstBusSyncReply
220 bus_callback (GstBus * bus, GstMessage * message, gpointer data)
222 const GstStructure *st;
224 GstBuffer *buf = NULL;
225 guint8 *data_buf = NULL;
228 gchar *preview_filename = NULL;
232 switch (GST_MESSAGE_TYPE (message)) {
233 case GST_MESSAGE_ERROR:{
237 gst_message_parse_error (message, &err, &debug);
238 g_print ("Error: %s\n", err->message);
242 /* Write debug graph to file */
243 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camera_bin),
244 GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.error");
246 g_main_loop_quit (loop);
249 case GST_MESSAGE_STATE_CHANGED:
250 if (GST_IS_BIN (GST_MESSAGE_SRC (message))) {
251 GstState oldstate, newstate;
253 gst_message_parse_state_changed (message, &oldstate, &newstate, NULL);
254 GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-changed: %s -> %s",
255 gst_element_state_get_name (oldstate),
256 gst_element_state_get_name (newstate));
259 case GST_MESSAGE_EOS:
261 GST_INFO ("got eos() - should not happen");
262 g_main_loop_quit (loop);
265 st = gst_message_get_structure (message);
267 if (gst_structure_has_name (message->structure, "prepare-xwindow-id")) {
269 gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC
271 gst_message_unref (message);
275 } else if (gst_structure_has_name (st, "image-captured")) {
276 GST_DEBUG ("image-captured");
277 } else if (gst_structure_has_name (st, "preview-image")) {
278 GST_DEBUG ("preview-image");
279 //extract preview-image from msg
280 image = gst_structure_get_value (st, "buffer");
282 buf = gst_value_get_buffer (image);
283 data_buf = GST_BUFFER_DATA (buf);
284 size = GST_BUFFER_SIZE (buf);
285 preview_filename = g_strdup_printf ("test_vga.rgb");
286 caps_string = gst_caps_to_string (GST_BUFFER_CAPS (buf));
287 g_print ("writing buffer to %s, buffer caps: %s\n",
288 preview_filename, caps_string);
289 g_free (caps_string);
290 f = g_fopen (preview_filename, "w");
292 written = fwrite (data_buf, size, 1, f);
294 g_print ("errro writing file\n");
298 g_print ("error opening file for raw image writing\n");
300 g_free (preview_filename);
304 /* unhandled message */
315 cleanup_pipeline (void)
318 GST_INFO_OBJECT (camera_bin, "stopping and destroying");
319 gst_element_set_state (camera_bin, GST_STATE_NULL);
320 gst_object_unref (camera_bin);
326 setup_pipeline_element (const gchar * property_name, const gchar * element_name,
327 GstElement ** res_elem)
330 GstElement *elem = NULL;
333 elem = gst_element_factory_make (element_name, NULL);
335 g_object_set (camera_bin, property_name, elem, NULL);
337 GST_WARNING ("can't create element '%s' for property '%s'", element_name,
342 GST_DEBUG ("no element for property '%s' given", property_name);
350 create_audioencoder_bin (void)
352 GstElement *bin, *aenc, *filter;
356 bin = gst_bin_new ("aebin");
357 filter = gst_element_factory_make ("capsfilter", "aefilter");
358 aenc = gst_element_factory_make (audioenc_name, "aenc");
360 if (!g_ascii_strcasecmp (audioenc_name, "pulsesrc")) {
361 g_object_set (G_OBJECT (aenc),
362 "bitrate", audio_bitrate, "profile", 2, NULL);
365 audio_caps = gst_caps_new_simple ("audio/x-raw-int",
366 "channels", G_TYPE_INT, audio_channels,
367 "rate", G_TYPE_INT, audio_samplerate, NULL);
370 g_warning ("error generating caps");
373 g_object_set (G_OBJECT (filter), "caps", audio_caps, NULL);
375 gst_caps_unref (audio_caps);
377 gst_bin_add_many (GST_BIN (bin), filter, aenc, NULL);
378 gst_element_link (filter, aenc);
380 pad = gst_element_get_static_pad (filter, "sink");
381 gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
382 gst_object_unref (GST_OBJECT (pad));
384 pad = gst_element_get_static_pad (aenc, "src");
385 gst_element_add_pad (bin, gst_ghost_pad_new ("src", pad));
386 gst_object_unref (GST_OBJECT (pad));
392 setup_pipeline (void)
396 GstElement *vmux = NULL, *ienc = NULL, *sink = NULL, *aenc = NULL, *ipp =
398 GstCaps *filter_caps = NULL;
400 camera_bin = gst_element_factory_make ("camerabin", NULL);
401 if (NULL == camera_bin) {
402 g_warning ("can't create camerabin element\n");
405 g_object_set (camera_bin, "flags", flags, NULL);
407 g_signal_connect (camera_bin, "image-done", (GCallback) img_capture_done,
410 bus = gst_pipeline_get_bus (GST_PIPELINE (camera_bin));
411 gst_bus_set_sync_handler (bus, bus_callback, NULL);
412 gst_object_unref (bus);
414 GST_INFO_OBJECT (camera_bin, "camerabin created");
416 /* configure used elements */
417 res &= setup_pipeline_element ("viewfinder-sink", vfsink_name, &sink);
418 res &= setup_pipeline_element ("audio-source", audiosrc_name, NULL);
419 res &= setup_pipeline_element ("video-source", videosrc_name, NULL);
420 res &= setup_pipeline_element ("video-source-filter", video_src_filter, NULL);
421 res &= setup_pipeline_element ("viewfinder-filter", viewfinder_filter, NULL);
424 aenc = create_audioencoder_bin ();
426 g_object_set (camera_bin, "audio-encoder", aenc, NULL);
428 GST_WARNING ("Could not make audio encoder element");
431 res &= setup_pipeline_element ("video-encoder", videoenc_name, NULL);
432 res &= setup_pipeline_element ("image-encoder", imageenc_name, &ienc);
433 res &= setup_pipeline_element ("image-post-processing", imagepp_name, &ipp);
434 res &= setup_pipeline_element ("video-muxer", videomux_name, &vmux);
438 GST_INFO_OBJECT (camera_bin, "elements created");
442 filter_caps = gst_caps_from_string (src_format);
443 } else if (src_csp && strlen (src_csp) == 4) {
444 /* Set requested colorspace format, this is needed if the default
445 colorspace negotiated for viewfinder doesn't match with e.g. encoders. */
446 filter_caps = gst_caps_new_simple ("video/x-raw-yuv",
447 "format", GST_TYPE_FOURCC,
448 GST_MAKE_FOURCC (src_csp[0], src_csp[1], src_csp[2], src_csp[3]), NULL);
452 g_object_set (camera_bin, "filter-caps", filter_caps, NULL);
453 gst_caps_unref (filter_caps);
456 g_object_set (sink, "sync", TRUE, NULL);
458 GST_INFO_OBJECT (camera_bin, "elements configured");
460 /* configure a resolution and framerate */
462 g_signal_emit_by_name (camera_bin, "set-video-resolution-fps", image_width,
463 image_height, view_framerate_num, view_framerate_den, NULL);
465 g_signal_emit_by_name (camera_bin, "set-image-resolution", image_width,
469 if (GST_STATE_CHANGE_FAILURE ==
470 gst_element_set_state (camera_bin, GST_STATE_READY)) {
471 g_warning ("can't set camerabin to ready\n");
474 GST_INFO_OBJECT (camera_bin, "camera ready");
476 if (GST_STATE_CHANGE_FAILURE ==
477 gst_element_set_state (camera_bin, GST_STATE_PLAYING)) {
478 g_warning ("can't set camerabin to playing\n");
481 GST_INFO_OBJECT (camera_bin, "camera started");
489 stop_capture (gpointer user_data)
491 g_signal_emit_by_name (camera_bin, "capture-stop", 0);
492 if (capture_count < capture_total) {
493 g_idle_add ((GSourceFunc) run_pipeline, NULL);
495 g_main_loop_quit (loop);
501 set_metadata (GstElement * camera)
503 GstTagSetter *setter = GST_TAG_SETTER (camera);
504 GTimeVal time = { 0, 0 };
506 GDate *date = g_date_new ();
508 g_get_current_time (&time);
509 g_date_set_time_val (date, &time);
511 desc_str = g_strdup_printf ("captured by %s", g_get_real_name ());
513 gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
515 GST_TAG_DESCRIPTION, desc_str,
516 GST_TAG_TITLE, "gst-camerabin-test capture",
517 GST_TAG_GEO_LOCATION_LONGITUDE, 1.0,
518 GST_TAG_GEO_LOCATION_LATITUDE, 2.0,
519 GST_TAG_GEO_LOCATION_ELEVATION, 3.0,
520 "device-make", "gst-camerabin-test make",
521 "device-model", "gst-camerabin-test model", NULL);
528 run_pipeline (gpointer user_data)
530 GstCaps *preview_caps = NULL;
532 g_object_set (camera_bin, "mode", mode, NULL);
534 if (preview_caps_name != NULL) {
535 preview_caps = gst_caps_from_string (preview_caps_name);
537 g_object_set (camera_bin, "preview-caps", preview_caps, NULL);
538 GST_DEBUG ("Preview caps set");
540 GST_DEBUG ("Preview caps set but could not create caps from string");
543 set_metadata (camera_bin);
546 gchar *filename_str = filename->str;
547 filename_str = g_strdup_printf ("%s%d", filename->str, capture_count);
548 g_object_set (camera_bin, "filename", filename_str, NULL);
549 g_free (filename_str);
551 g_object_set (camera_bin, "filename", filename->str, NULL);
554 g_object_set (camera_bin, "ev-compensation", ev_compensation, NULL);
555 g_object_set (camera_bin, "aperture", aperture, NULL);
556 g_object_set (camera_bin, "flash-mode", flash_mode, NULL);
557 g_object_set (camera_bin, "scene-mode", scene_mode, NULL);
558 g_object_set (camera_bin, "exposure", exposure, NULL);
559 g_object_set (camera_bin, "iso-speed", iso_speed, NULL);
560 g_object_set (camera_bin, "white-balance-mode", wb_mode, NULL);
561 g_object_set (camera_bin, "colour-tone-mode", color_mode, NULL);
562 g_object_set (camera_bin, "mute", mute, NULL);
563 g_object_set (camera_bin, "zoom", zoom, NULL);
566 g_signal_emit_by_name (camera_bin, "capture-start", 0);
570 g_timeout_add ((capture_time * 1000), (GSourceFunc) stop_capture, NULL);
577 main (int argc, char *argv[])
579 gchar *target_times = NULL;
580 gchar *ev_option = NULL;
581 gchar *fn_option = NULL;
583 GOptionEntry options[] = {
584 {"ev-compensation", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING,
586 "EV compensation (-2.5..2.5, default = 0)", NULL},
587 {"aperture", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &aperture,
588 "Aperture (size of lens opening, default = 0 (auto))", NULL},
589 {"flash-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
591 "Flash mode (default = 0 (auto))", NULL},
592 {"scene-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
594 "Scene mode (default = 6 (auto))", NULL},
595 {"exposure", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT64,
597 "Exposure (default = 0 (auto))", NULL},
598 {"iso-speed", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
600 "ISO speed (default = 0 (auto))", NULL},
601 {"white-balance-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
603 "White balance mode (default = 0 (auto))", NULL},
604 {"colour-tone-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
606 "Colour tone mode (default = 0 (auto))", NULL},
607 {"directory", '\0', 0, G_OPTION_ARG_STRING, &fn_option,
608 "Directory for capture file(s) (default is current directory)", NULL},
609 {"mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &mode,
610 "Capture mode (default = 0 (image), 1 = video)", NULL},
611 {"capture-time", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
613 "Time to capture video in seconds (default = 10)", NULL},
614 {"capture-total", '\0', 0, G_OPTION_ARG_INT, &capture_total,
615 "Total number of captures to be done (default = 1)", NULL},
616 {"flags", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &flags,
617 "Flags for camerabin, (default = 0x9)", NULL},
618 {"mute", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING, &mute,
619 "Mute audio (default = 0 (no))", NULL},
620 {"zoom", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING, &zoom,
621 "Zoom (100 = 1x (default), 200 = 2x etc.)", NULL},
622 {"audio-src", '\0', 0, G_OPTION_ARG_STRING, &audiosrc_name,
623 "Audio source used in video recording", NULL},
624 {"audio-bitrate", '\0', 0, G_OPTION_ARG_INT, &audio_bitrate,
625 "Audio bitrate (default 128000)", NULL},
626 {"audio-samplerate", '\0', 0, G_OPTION_ARG_INT, &audio_samplerate,
627 "Audio samplerate (default 48000)", NULL},
628 {"audio-channels", '\0', 0, G_OPTION_ARG_INT, &audio_channels,
629 "Audio channels (default 1)", NULL},
630 {"video-src", '\0', 0, G_OPTION_ARG_STRING, &videosrc_name,
631 "Video source used in still capture and video recording", NULL},
632 {"audio-enc", '\0', 0, G_OPTION_ARG_STRING, &audioenc_name,
633 "Audio encoder used in video recording", NULL},
634 {"video-enc", '\0', 0, G_OPTION_ARG_STRING, &videoenc_name,
635 "Video encoder used in video recording", NULL},
636 {"image-enc", '\0', 0, G_OPTION_ARG_STRING, &imageenc_name,
637 "Image encoder used in still capture", NULL},
638 {"image-pp", '\0', 0, G_OPTION_ARG_STRING, &imagepp_name,
639 "Image post-processing element", NULL},
640 {"video-mux", '\0', 0, G_OPTION_ARG_STRING, &videomux_name,
641 "Muxer used in video recording", NULL},
642 {"viewfinder-sink", '\0', 0, G_OPTION_ARG_STRING, &vfsink_name,
643 "Viewfinder sink (default = fakesink)", NULL},
644 {"image-width", '\0', 0, G_OPTION_ARG_INT, &image_width,
645 "Width for image capture", NULL},
646 {"image-height", '\0', 0, G_OPTION_ARG_INT, &image_height,
647 "Height for image capture", NULL},
648 {"view-framerate-num", '\0', 0, G_OPTION_ARG_INT, &view_framerate_num,
649 "Framerate numerator for viewfinder", NULL},
650 {"view-framerate-den", '\0', 0, G_OPTION_ARG_INT, &view_framerate_den,
651 "Framerate denominator for viewfinder", NULL},
652 {"src-colorspace", '\0', 0, G_OPTION_ARG_STRING, &src_csp,
653 "Colorspace format for video source (e.g. YUY2, UYVY)", NULL},
654 {"src-format", '\0', 0, G_OPTION_ARG_STRING, &src_format,
655 "Video format for video source", NULL},
656 {"preview-caps", '\0', 0, G_OPTION_ARG_STRING, &preview_caps_name,
657 "Preview caps (e.g. video/x-raw-rgb,width=320,height=240)", NULL},
658 {"video-source-filter", '\0', 0, G_OPTION_ARG_STRING, &video_src_filter,
659 "Video filter to process all frames from video source", NULL},
660 {"viewfinder-filter", '\0', 0, G_OPTION_ARG_STRING, &viewfinder_filter,
661 "Filter to process all frames going to viewfinder sink", NULL},
662 {"x-width", '\0', 0, G_OPTION_ARG_INT, &x_width,
663 "X window width (default = 320)", NULL},
664 {"x-height", '\0', 0, G_OPTION_ARG_INT, &x_height,
665 "X window height (default = 240)", NULL},
672 /* if we fail to create xwindow should we care? */
673 create_host_window ();
675 if (!g_thread_supported ())
676 g_thread_init (NULL);
678 ctx = g_option_context_new ("\n\ncamerabin command line test application.");
679 g_option_context_add_main_entries (ctx, options, NULL);
680 g_option_context_add_group (ctx, gst_init_get_option_group ());
681 if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
682 g_print ("Error initializing: %s\n", err->message);
685 g_option_context_free (ctx);
687 GST_DEBUG_CATEGORY_INIT (camerabin_test, "camerabin-test", 0,
690 /* FIXME: error handling */
691 if (ev_option != NULL)
692 ev_compensation = strtod (ev_option, (char **) NULL);
694 if (vfsink_name == NULL)
695 vfsink_name = g_strdup ("fakesink");
697 filename = g_string_new (fn_option);
698 if (filename->len == 0)
699 filename = g_string_append (filename, ".");
701 filename = g_string_append (filename, "/test_%04u");
703 filename = g_string_append (filename, ".mp4");
705 filename = g_string_append (filename, ".jpg");
708 if (setup_pipeline ()) {
709 loop = g_main_loop_new (NULL, FALSE);
710 g_idle_add ((GSourceFunc) run_pipeline, NULL);
711 g_main_loop_run (loop);
713 g_main_loop_unref (loop);
716 g_string_free (filename, TRUE);
718 g_free (audiosrc_name);
719 g_free (videosrc_name);
720 g_free (audioenc_name);
721 g_free (videoenc_name);
722 g_free (imageenc_name);
723 g_free (imagepp_name);
724 g_free (videomux_name);
725 g_free (vfsink_name);
728 g_free (target_times);
731 XDestroyWindow (display, window);
734 XCloseDisplay (display);