<climits> is needed for INT_MAX in agg2 headers
[gnash.git] / utilities / findwebcams.cpp
blob288efb12d0fe9b79f8d11b180b46e90817900732
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 // Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program 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
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifdef HAVE_CONFIG_H
20 #include "gnashconfig.h"
21 #endif
23 #include "rc.h"
24 #include "gst/gst.h"
25 #include <gst/interfaces/propertyprobe.h>
27 #include <vector>
28 #include <string>
30 namespace {
31 //get rc file for webcam selection
32 gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
35 class data {
36 public:
37 data();
38 gchar* deviceName;
39 gchar* deviceType;
40 gint deviceNumber;
41 gboolean duplicate;
44 data::data() {
45 deviceName = NULL;
46 deviceType = NULL;
47 deviceNumber = -1;
48 duplicate = false;
51 gint numDuplicates = 0;
53 gint findVidDevs(std::vector<data*>& vidVect) {
54 gint numdevs = 0;
56 //vid test source
57 GstElement *element;
58 element = gst_element_factory_make ("videotestsrc", "vidtestsrc");
60 if (element == NULL) {
61 vidVect.push_back(NULL);
62 numdevs += 1;
63 } else {
64 vidVect.push_back(new data);
65 vidVect[numdevs]->deviceName = g_strdup_printf("videotestsrc");
66 vidVect[numdevs]->deviceType = g_strdup_printf("videotestsrc");
67 vidVect[numdevs]->deviceNumber = 0;
68 numdevs += 1;
71 //video4linux source
72 GstPropertyProbe *probe;
73 GValueArray *devarr;
74 element = NULL;
76 element = gst_element_factory_make ("v4lsrc", "v4lvidsrc");
77 probe = GST_PROPERTY_PROBE (element);
78 devarr = gst_property_probe_probe_and_get_values_name (probe, "device");
79 for (size_t i = 0; devarr != NULL && i < devarr->n_values; ++i) {
80 GValue *val;
81 gchar *dev_name = NULL;
83 val = g_value_array_get_nth (devarr, i);
84 g_object_set (element, "device", g_value_get_string (val), NULL);
85 gst_element_set_state (element, GST_STATE_PLAYING);
86 g_object_get (element, "device-name", &dev_name, NULL);
87 gst_element_set_state (element, GST_STATE_NULL);
88 if (strcmp(dev_name, "null") == 0) {
89 g_print("no v4l video sources found\n");
91 else {
92 vidVect.push_back(new data);
93 vidVect[numdevs]->deviceType = g_strdup_printf("v4lsrc");
94 vidVect[numdevs]->deviceName = dev_name;
95 vidVect[numdevs]->deviceNumber = numdevs;
96 numdevs += 1;
99 if (devarr) {
100 g_value_array_free (devarr);
104 //video4linux2 source
105 probe = NULL;
106 element = NULL;
107 devarr = NULL;
108 gint g;
110 element = gst_element_factory_make ("v4l2src", "v4l2vidsrc");
111 probe = GST_PROPERTY_PROBE (element);
112 devarr = gst_property_probe_probe_and_get_values_name (probe, "device");
113 for (size_t i = 0; devarr != NULL && i < devarr->n_values; ++i) {
114 GValue *val;
115 gchar *dev_name = NULL;
117 val = g_value_array_get_nth (devarr, i);
118 g_object_set (element, "device", g_value_get_string (val), NULL);
119 gst_element_set_state (element, GST_STATE_PLAYING);
120 g_object_get (element, "device-name", &dev_name, NULL);
121 gst_element_set_state (element, GST_STATE_NULL);
122 if (strcmp(dev_name, "null") == 0) {
123 g_print("no v4l2 video sources found.\n");
125 else {
126 vidVect.push_back(new data);
127 vidVect[numdevs]->deviceType = g_strdup_printf("v4l2src");
128 vidVect[numdevs]->deviceName = dev_name;
129 vidVect[numdevs]->deviceNumber = numdevs;
130 //mark duplicates (we like v4l2 sources more than v4l, so if
131 //they're both detected, mark the v4l source as a duplicate)
132 for (g=1; g < (vidVect.size()-1); g++) {
133 if (strcmp(vidVect[numdevs]->deviceName,
134 vidVect[g]->deviceName) == 0) {
135 vidVect[g]->duplicate = true;
136 numDuplicates += 1;
139 numdevs += 1;
142 if (devarr) {
143 g_value_array_free (devarr);
145 return numdevs;
148 int main () {
149 //initialize gstreamer to probe for devs
150 gst_init(NULL, NULL);
151 gint numdevs = 0;
152 std::vector<data*> vidVector;
154 int fromrc = rcfile.getWebcamDevice();
156 if (fromrc == -1) {
157 g_print("\nUse this utility to set your desired default webcam device.\n");
158 numdevs = findVidDevs(vidVector);
159 g_print("\nINFO: these devices were ignored because they are supported by both");
160 g_print("\nvideo4linux and video4linux2:\n\n");
161 for (size_t i = 0; i < numdevs; ++i) {
162 if (vidVector[i]->duplicate == true) {
163 g_print(" %s (%s)\n", vidVector[i]->deviceName, vidVector[i]->deviceType);
166 g_print("\nGnash interacts with v4l2 sources better than v4l sources, thus the");
167 g_print("\nv4l sources will not be printed in the list below.\n");
168 g_print("\nFound %d video devices: \n\n", (numdevs - numDuplicates));
169 gint counter = 0;
170 for (size_t i = 0; i < numdevs; ++i)
172 if (i == 0 && (vidVector[i] != 0)) {
173 g_print(" %d. Video Test Source (videotestsrc)\n", i, i);
174 counter++;
175 } else if (i == 0 && (vidVector[i] == 0)) {
176 g_print("no test video device available");
177 } else {
178 if (vidVector[i]->duplicate != true) {
179 g_print(" %d. %s (%s)\n", counter, vidVector[i]->deviceName,
180 vidVector[i]->deviceType);
181 counter++;
185 //prompt user for device selection
186 int dev_select = -1;
187 std::string fromCin;
188 do {
189 dev_select = -1;
190 g_print("\nChoose the device you would like to use (0-%d): ",
191 (numdevs - numDuplicates - 1));
192 std::cin >> fromCin;
193 if (fromCin.size() != 1) {
194 dev_select = -1;
195 } else if (fromCin[0] == '0') {
196 dev_select = 0;
197 } else {
198 dev_select = atoi(fromCin.c_str());
200 if ((dev_select < 0) || (dev_select > (numdevs - numDuplicates - 1))) {
201 g_print("You must make a valid device selection\n");
203 } while ((dev_select < 0) || (dev_select > (numdevs - numDuplicates - 1)));
204 g_print("\nTo select this camera, add this line to your gnashrc file:\n");
205 g_print("set webcamDevice %d\n", vidVector[dev_select + numDuplicates]->deviceNumber);
206 } else {
207 numdevs = findVidDevs(vidVector);
208 if (fromrc <= (vidVector.size() - 1)) {
209 g_print("\nThe gnashrc file reports default webcam is set to:\n");
210 g_print("%s (%s)\n", vidVector[fromrc]->deviceName,
211 vidVector[fromrc]->deviceType);
212 g_print("To change this setting, delete the 'set webcamDevice' line\n");
213 g_print("from your gnashrc file and re-run this program.\n\n");
214 } else {
215 g_print("\nYou have an invalid webcam chosen in your gnashrc file.\n");
216 g_print("Try reattaching the device or deleting the value from gnashrc\n");
217 g_print("and running this program again\n");
220 return 0;