1 /* GStreamer
2 *
3 * Copyright (C) 2015 Samsung Electronics. All rights reserved.
4 * Author: Thiago Santos <thiagoss@osg.samsung.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21 /* demo for showing v4l2src renegotiating */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gst/gst.h>
28
29 /* Options */
30 static const gchar *device = "/dev/video0";
31 static const gchar *videosink = "autovideosink";
32 static const gchar *io_mode = "mmap";
33 static const gchar *def_resolutions[] = {
34 "320x240",
35 "1280x720",
36 "640x480",
37 NULL
38 };
39
40 static const gchar **resolutions = def_resolutions;
41
42 static GOptionEntry entries[] = {
43 {"device", 'd', 0, G_OPTION_ARG_STRING, &device, "V4L2 Camera Device",
44 NULL},
45 {"videosink", 's', 0, G_OPTION_ARG_STRING, &videosink, "Video Sink to use",
46 NULL},
47 {"io-mode", 'z', 0, G_OPTION_ARG_STRING, &io_mode,
48 "Configure the \"io-mode\" property on v4l2scr", NULL},
49 {"resolution", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &resolutions,
50 "Add a resolution to the list", NULL},
51 {NULL}
52 };
53
54 static GMainLoop *loop;
55 static GstElement *pipeline;
56 static GstElement *src, *capsfilter;
57 static gint resolution_index = 0;
58
59 static gboolean
bus_callback(GstBus * bus,GstMessage * message,gpointer data)60 bus_callback (GstBus * bus, GstMessage * message, gpointer data)
61 {
62 switch (message->type) {
63 case GST_MESSAGE_EOS:
64 g_main_loop_quit (loop);
65 break;
66 case GST_MESSAGE_ERROR:{
67 GError *gerror;
68 gchar *debug;
69
70 gst_message_parse_error (message, &gerror, &debug);
71 gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
72 g_error_free (gerror);
73 g_free (debug);
74 g_main_loop_quit (loop);
75 break;
76 }
77 default:
78 break;
79 }
80
81 return TRUE;
82 }
83
84 static gboolean
change_caps(gpointer data)85 change_caps (gpointer data)
86 {
87 GstCaps *caps;
88 GStrv res;
89 gchar *caps_str;
90
91 if (!resolutions[resolution_index]) {
92 gst_element_send_event (pipeline, gst_event_new_eos ());
93 return FALSE;
94 }
95
96 g_print ("Setting resolution to '%s'\n", resolutions[resolution_index]);
97
98 res = g_strsplit (resolutions[resolution_index++], "x", 2);
99 if (!res[0] || !res[1]) {
100 g_warning ("Can't parse resolution: %s", resolutions[resolution_index - 1]);
101 g_strfreev (res);
102 return TRUE;
103 }
104
105 caps_str = g_strdup_printf ("video/x-raw,width=%s,height=%s", res[0], res[1]);
106 caps = gst_caps_from_string (caps_str);
107 g_object_set (capsfilter, "caps", caps, NULL);
108
109 g_strfreev (res);
110 g_free (caps_str);
111 gst_caps_unref (caps);
112
113 return TRUE;
114 }
115
116 gint
main(gint argc,gchar ** argv)117 main (gint argc, gchar ** argv)
118 {
119 GstBus *bus;
120 GError *error = NULL;
121 GOptionContext *context;
122 gchar *desc;
123 gboolean ret;
124
125 context = g_option_context_new ("- test v4l2src live renegotition");
126 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
127 g_option_context_add_group (context, gst_init_get_option_group ());
128 ret = g_option_context_parse (context, &argc, &argv, &error);
129 g_option_context_free (context);
130
131 if (!ret) {
132 g_print ("option parsing failed: %s\n", error->message);
133 g_error_free (error);
134 return 1;
135 }
136
137 loop = g_main_loop_new (NULL, FALSE);
138
139 desc = g_strdup_printf ("v4l2src name=src device=\"%s\" io-mode=\"%s\" "
140 "! capsfilter name=cf ! %s", device, io_mode, videosink);
141 pipeline = gst_parse_launch (desc, &error);
142 g_free (desc);
143 if (!pipeline) {
144 g_print ("failed to create pipeline: %s", error->message);
145 g_error_free (error);
146 return 1;
147 }
148
149 src = gst_bin_get_by_name (GST_BIN (pipeline), "src");
150 capsfilter = gst_bin_get_by_name (GST_BIN (pipeline), "cf");
151
152 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
153 gst_bus_add_watch (bus, bus_callback, NULL);
154 gst_object_unref (bus);
155
156 change_caps (NULL);
157
158 /* play and wait */
159 gst_element_set_state (pipeline, GST_STATE_PLAYING);
160
161 g_timeout_add_seconds (3, change_caps, NULL);
162
163 /* mainloop and wait for eos */
164 g_main_loop_run (loop);
165
166 /* stop and cleanup */
167 gst_element_set_state (pipeline, GST_STATE_NULL);
168 gst_object_unref (src);
169 gst_object_unref (capsfilter);
170 gst_object_unref (GST_OBJECT (pipeline));
171 g_main_loop_unref (loop);
172 return 0;
173 }
174