Update with current status
[gnash.git] / utilities / findwebcams.cpp
blobe3bcf63ff0799a9cf4fdc087d3771ed0edde658d
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software 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 "gst/GlibDeprecated.h"
25 #include <vector>
26 #include <string>
27 #include <iostream>
29 #include "rc.h"
30 #include "gst/gst.h"
31 #include <gst/interfaces/propertyprobe.h>
33 namespace {
34 //get rc file for webcam selection
35 gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
38 class data {
39 public:
40 data();
41 gchar* deviceName;
42 gchar* deviceType;
43 gint deviceNumber;
44 gboolean duplicate;
47 data::data() {
48 deviceName = nullptr;
49 deviceType = nullptr;
50 deviceNumber = -1;
51 duplicate = false;
54 gint numDuplicates = 0;
56 size_t findVidDevs(std::vector<data*>& vidVect) {
57 gint numdevs = 0;
59 //vid test source
60 GstElement *element;
61 element = gst_element_factory_make ("videotestsrc", "vidtestsrc");
63 if (element == nullptr) {
64 vidVect.push_back(nullptr);
65 numdevs += 1;
66 } else {
67 vidVect.push_back(new data);
68 vidVect[numdevs]->deviceName = g_strdup_printf("videotestsrc");
69 vidVect[numdevs]->deviceType = g_strdup_printf("videotestsrc");
70 vidVect[numdevs]->deviceNumber = 0;
71 numdevs += 1;
74 //video4linux source
75 GstPropertyProbe *probe;
76 GValueArray *devarr;
77 element = nullptr;
79 element = gst_element_factory_make ("v4lsrc", "v4lvidsrc");
80 probe = GST_PROPERTY_PROBE (element);
81 devarr = gst_property_probe_probe_and_get_values_name (probe, "device");
82 for (size_t i = 0; devarr != nullptr && i < devarr->n_values; ++i) {
83 GValue *val;
84 gchar *dev_name = nullptr;
86 val = g_value_array_get_nth (devarr, i);
87 g_object_set (element, "device", g_value_get_string (val), NULL);
88 gst_element_set_state (element, GST_STATE_PLAYING);
89 g_object_get (element, "device-name", &dev_name, NULL);
90 gst_element_set_state (element, GST_STATE_NULL);
91 if (strcmp(dev_name, "null") == 0) {
92 std::cout << "no v4l video sources found" << std::endl;
94 else {
95 vidVect.push_back(new data);
96 vidVect[numdevs]->deviceType = g_strdup_printf("v4lsrc");
97 vidVect[numdevs]->deviceName = dev_name;
98 vidVect[numdevs]->deviceNumber = numdevs;
99 numdevs += 1;
102 if (devarr) {
103 g_value_array_free (devarr);
107 //video4linux2 source
108 probe = nullptr;
109 element = nullptr;
110 devarr = nullptr;
112 element = gst_element_factory_make ("v4l2src", "v4l2vidsrc");
113 probe = GST_PROPERTY_PROBE (element);
114 devarr = gst_property_probe_probe_and_get_values_name (probe, "device");
115 for (size_t i = 0; devarr != nullptr && i < devarr->n_values; ++i) {
116 GValue *val;
117 gchar *dev_name = nullptr;
119 val = g_value_array_get_nth (devarr, i);
120 g_object_set (element, "device", g_value_get_string (val), NULL);
121 gst_element_set_state (element, GST_STATE_PLAYING);
122 g_object_get (element, "device-name", &dev_name, NULL);
123 gst_element_set_state (element, GST_STATE_NULL);
124 if (strcmp(dev_name, "null") == 0) {
125 std::cout << "no v4l2 video sources found." << std::endl;
127 else {
128 vidVect.push_back(new data);
129 vidVect[numdevs]->deviceType = g_strdup_printf("v4l2src");
130 vidVect[numdevs]->deviceName = dev_name;
131 vidVect[numdevs]->deviceNumber = numdevs;
132 //mark duplicates (we like v4l2 sources more than v4l, so if
133 //they're both detected, mark the v4l source as a duplicate)
134 for (size_t g=1; g < (vidVect.size()-1); g++) {
135 if (strcmp(vidVect[numdevs]->deviceName,
136 vidVect[g]->deviceName) == 0) {
137 vidVect[g]->duplicate = true;
138 numDuplicates += 1;
141 numdevs += 1;
144 if (devarr) {
145 g_value_array_free (devarr);
147 return numdevs;
150 int main () {
151 //initialize gstreamer to probe for devs
152 gst_init(nullptr, nullptr);
153 size_t numdevs = 0;
154 std::vector<data*> vidVector;
156 int fromrc = rcfile.getWebcamDevice();
158 if (fromrc == -1) {
159 std::cout << std::endl
160 << "Use this utility to set your desired default webcam device." << std::endl;
161 numdevs = findVidDevs(vidVector);
162 std::cout << std::endl
163 << "INFO: these devices were ignored because they are supported by both" << std::endl
164 << "video4linux and video4linux2:" << std::endl << std::endl;
165 for (size_t i = 0; i < numdevs; ++i) {
166 if (vidVector[i]->duplicate == true) {
167 std::cout << " " << vidVector[i]->deviceName
168 << " (" << vidVector[i]->deviceType << ")" << std::endl;
171 std::cout << std::endl
172 << "Gnash interacts with v4l2 sources better than v4l sources, thus the" << std::endl
173 << "v4l sources will not be printed in the list below." << std::endl
174 << std::endl
175 << "Found " << (numdevs - numDuplicates)
176 << " video devices: " << std::endl << std::endl;
177 gint counter = 0;
178 for (size_t i = 0; i < numdevs; ++i)
180 if (i == 0 && (vidVector[i] != nullptr)) {
181 std::cout << " " << i
182 << ". Video Test Source (videotestsrc)" << std::endl;
183 counter++;
184 } else if (i == 0 && (vidVector[i] == nullptr)) {
185 std::cout << "no test video device available";
186 } else {
187 if (vidVector[i]->duplicate != true) {
188 std::cout << " " << counter << ". "
189 << vidVector[i]->deviceName
190 << " (" << vidVector[i]->deviceType << ")" << std::endl;
191 counter++;
195 //prompt user for device selection
196 int dev_select = -1;
197 std::string fromCin;
198 do {
199 dev_select = -1;
200 std::cout << std::endl
201 << "Choose the device you would like to use (0-"
202 << (numdevs - numDuplicates - 1) << "): ";
203 std::cin >> fromCin;
204 if (fromCin.size() != 1) {
205 dev_select = -1;
206 } else if (fromCin[0] == '0') {
207 dev_select = 0;
208 } else {
209 dev_select = atoi(fromCin.c_str());
211 if ((dev_select < 0) || (dev_select > ((int)numdevs - numDuplicates - 1))) {
212 std::cout << "You must make a valid device selection" << std::endl;
214 } while ((dev_select < 0) || (dev_select > ((int)numdevs - numDuplicates - 1)));
215 std::cout << std::endl
216 << "To select this camera, add this line to your gnashrc file:" << std::endl
217 << "set webcamDevice "
218 << (vidVector[dev_select + numDuplicates]->deviceNumber) << std::endl;
219 } else {
220 numdevs = findVidDevs(vidVector);
221 if ((size_t)fromrc <= (vidVector.size() - 1)) {
222 std::cout << std::endl
223 << "The gnashrc file reports default webcam is set to:" << std::endl
224 << vidVector[fromrc]->deviceName
225 << " (" << vidVector[fromrc]->deviceType << ")" << std::endl
226 << "To change this setting, delete the 'set webcamDevice' line" << std::endl
227 << "from your gnashrc file and re-run this program." << std::endl << std::endl;
228 } else {
229 std::cout << std::endl
230 << "You have an invalid webcam chosen in your gnashrc file." << std::endl
231 << "Try reattaching the device or deleting the value from gnashrc" << std::endl
232 << "and running this program again" << std::endl;
235 return 0;