Tizen 2.0 Release
[framework/multimedia/gst-plugins-good0.10.git] / tests / icles / v4l2src-test.c
1 /* GStreamer
2  *
3  * Copyright (C) 2006 Edgard Lima <edgard dot lima at indt dot org dot br>
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <getopt.h>
25
26 #include <gst/gst.h>
27 #include <gst/interfaces/tuner.h>
28 #include <gst/interfaces/colorbalance.h>
29 #include <gst/interfaces/videoorientation.h>
30
31 GstElement *pipeline, *source, *sink;
32 GMainLoop *loop;
33 volatile int exit_read = 0;
34
35 static void
36 print_options (void)
37 {
38   printf ("\nf - to change the fequency\n");
39   printf ("i - to change the input\n");
40   printf ("n - to change the norm\n");
41   printf ("c - list color balance\n");
42   printf ("v - change video orientarion\n");
43   printf ("e - to exit\n");
44 }
45
46 static void
47 run_options (char opt)
48 {
49   int res;
50
51   switch (opt) {
52     case 'f':
53     {
54       GstTuner *tuner = GST_TUNER (source);
55       GstTunerChannel *channel;
56       guint freq;
57
58       channel = gst_tuner_get_channel (tuner);
59
60       freq = gst_tuner_get_frequency (tuner, channel);
61
62       printf ("\ntype the new frequency (current = %u) (-1 to cancel): ", freq);
63       res = scanf ("%u", &freq);
64       if (res != 1 || freq != -1)
65         gst_tuner_set_frequency (tuner, channel, freq);
66     }
67       break;
68     case 'n':
69     {
70       GstTuner *tuner = GST_TUNER (source);
71       const GList *item, *list;
72       const GstTunerNorm *current_norm;
73       GstTunerNorm *norm = NULL;
74       gint index, next_norm;
75
76
77       list = gst_tuner_list_norms (tuner);
78
79       current_norm = gst_tuner_get_norm (tuner);
80
81       printf ("\nlist of norms:\n");
82       for (item = list, index = 0; item != NULL; item = item->next, ++index) {
83         norm = item->data;
84         if (current_norm == norm) {
85           printf (" * %u - %s\n", index, norm->label);
86         } else {
87           printf ("   %u - %s\n", index, norm->label);
88         }
89       }
90       printf ("\ntype the number of norm you want (-1 to cancel): ");
91       res = scanf ("%d", &next_norm);
92       if (res != 1 || next_norm < 0) {
93         break;
94       }
95       if (index <= next_norm) {
96         printf ("Norm %d not available\n", next_norm);
97         break;
98       }
99       for (item = list, index = 0; item != NULL && index <= next_norm;
100           item = item->next, ++index) {
101         norm = item->data;
102       }
103       if (norm)
104         gst_tuner_set_norm (tuner, norm);
105     }
106       break;
107     case 'i':
108     {
109       GstTuner *tuner = GST_TUNER (source);
110       const GList *item, *list;
111       const GstTunerChannel *current_channel;
112       GstTunerChannel *channel = NULL;
113       gint index, next_channel;
114
115
116       list = gst_tuner_list_channels (tuner);
117
118       current_channel = gst_tuner_get_channel (tuner);
119
120       printf ("\nlist of inputs:\n");
121       for (item = list, index = 0; item != NULL; item = item->next, ++index) {
122         channel = item->data;
123         if (current_channel == channel) {
124           printf (" * %u - %s\n", index, channel->label);
125         } else {
126           printf ("   %u - %s\n", index, channel->label);
127         }
128       }
129       printf ("\ntype the number of input you want (-1 to cancel): ");
130       res = scanf ("%d", &next_channel);
131       if (res != 1 || next_channel < 0) {
132         break;
133       }
134       if (index <= next_channel) {
135         printf ("Input %d not available\n", next_channel);
136         break;
137       }
138       for (item = list, index = 0; item != NULL && index <= next_channel;
139           item = item->next, ++index) {
140         channel = item->data;
141       }
142       if (channel)
143         gst_tuner_set_channel (tuner, channel);
144     }
145       break;
146     case 'e':
147       gst_element_set_state (pipeline, GST_STATE_NULL);
148       g_main_loop_quit (loop);
149       printf ("Bye\n");
150       g_thread_exit (0);
151       break;
152     case 'c':
153     {
154       GstColorBalance *balance = GST_COLOR_BALANCE (source);
155       const GList *controls;
156       GstColorBalanceChannel *channel;
157       const GList *item;
158       gint index, new_value;
159
160       controls = gst_color_balance_list_channels (balance);
161
162       printf ("\n");
163
164       if (controls == NULL) {
165         printf ("There is no list of colorbalance controls\n");
166         goto done;
167       }
168
169       if (controls) {
170         printf ("list of controls:\n");
171         for (item = controls, index = 0; item != NULL;
172             item = item->next, ++index) {
173           channel = item->data;
174           printf ("   %u - %s (%d - %d) = %d\n", index, channel->label,
175               channel->min_value, channel->max_value,
176               gst_color_balance_get_value (balance, channel));
177         }
178         printf ("\ntype the number of color control you want (-1 to cancel): ");
179         res = scanf ("%d", &new_value);
180         if (res != 1 || new_value == -1)
181           break;
182         for (item = controls, index = 0; item != NULL && index <= new_value;
183             item = item->next, ++index) {
184           channel = item->data;
185         }
186         printf ("   %u - %s (%d - %d) = %d, type the new value: ", index - 1,
187             channel->label, channel->min_value, channel->max_value,
188             gst_color_balance_get_value (balance, channel));
189         res = scanf ("%d", &new_value);
190         if (res != 1 || new_value == -1)
191           break;
192         gst_color_balance_set_value (balance, channel, new_value);
193       }
194     }
195     case 'v':
196     {
197       GstVideoOrientation *vidorient = GST_VIDEO_ORIENTATION (source);
198       gboolean flip = FALSE;
199       gint center = 0;
200
201       printf ("\n");
202
203       if (gst_video_orientation_get_hflip (vidorient, &flip)) {
204         gint new_value;
205
206         printf ("Horizontal flip is %s\n", flip ? "on" : "off");
207         printf ("\ntype 1 to toggle (-1 to cancel): ");
208         res = scanf ("%d", &new_value);
209         if (res != 1 || new_value == 1) {
210           flip = !flip;
211           if (gst_video_orientation_set_hflip (vidorient, flip)) {
212             gst_video_orientation_get_hflip (vidorient, &flip);
213             printf ("Now horizontal flip is %s\n", flip ? "on" : "off");
214           } else {
215             printf ("Error toggling horizontal flip\n");
216           }
217         } else {
218         }
219       } else {
220         printf ("Horizontal flip control not available\n");
221       }
222
223       if (gst_video_orientation_get_vflip (vidorient, &flip)) {
224         gint new_value;
225
226         printf ("\nVertical flip is %s\n", flip ? "on" : "off");
227         printf ("\ntype 1 to toggle (-1 to cancel): ");
228         res = scanf ("%d", &new_value);
229         if (res != 1 || new_value == 1) {
230           flip = !flip;
231           if (gst_video_orientation_set_vflip (vidorient, flip)) {
232             gst_video_orientation_get_vflip (vidorient, &flip);
233             printf ("Now vertical flip is %s\n", flip ? "on" : "off");
234           } else {
235             printf ("Error toggling vertical flip\n");
236           }
237         } else {
238         }
239       } else {
240         printf ("Vertical flip control not available\n");
241       }
242
243       if (gst_video_orientation_get_hcenter (vidorient, &center)) {
244         printf ("Horizontal center is %d\n", center);
245         printf ("\ntype the new horizontal center value (-1 to cancel): ");
246         res = scanf ("%d", &center);
247         if (res != 1 || center != -1) {
248           if (gst_video_orientation_set_hcenter (vidorient, center)) {
249             gst_video_orientation_get_hcenter (vidorient, &center);
250             printf ("Now horizontal center is %d\n", center);
251           } else {
252             printf ("Error setting horizontal center\n");
253           }
254         } else {
255         }
256       } else {
257         printf ("Horizontal center control not available\n");
258       }
259
260       if (gst_video_orientation_get_vcenter (vidorient, &center)) {
261         printf ("Vertical center is %d\n", center);
262         printf ("\ntype the new vertical center value (-1 to cancel): ");
263         res = scanf ("%d", &center);
264         if (res != 1 || center != -1) {
265           if (gst_video_orientation_set_vcenter (vidorient, center)) {
266             gst_video_orientation_get_vcenter (vidorient, &center);
267             printf ("Now vertical center is %d\n", center);
268           } else {
269             printf ("Error setting vertical center\n");
270           }
271         } else {
272         }
273       } else {
274         printf ("Vertical center control not available\n");
275       }
276
277     }
278       break;
279       break;
280     default:
281       if (opt != 10)
282         printf ("error: invalid option %c", opt);
283       break;
284   }
285
286 done:
287
288   return;
289
290 }
291
292 static gpointer
293 read_user (gpointer data)
294 {
295
296   char opt;
297
298   while (!exit_read) {
299
300     print_options ();
301
302     do {
303       opt = getchar ();
304       if (exit_read) {
305         break;
306       }
307     } while (opt == '\n');
308
309     run_options (opt);
310
311   }
312
313   return NULL;
314
315 }
316
317 static gboolean
318 my_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
319 {
320
321   switch (GST_MESSAGE_TYPE (message)) {
322     case GST_MESSAGE_ERROR:{
323       GError *err;
324       gchar *debug;
325       gchar *str;
326
327       gst_message_parse_error (message, &err, &debug);
328       str = gst_element_get_name (message->src);
329       g_print ("%s error: %s\n", str, err->message);
330       g_free (str);
331       g_print ("Debug: %s\n", debug);
332
333       g_error_free (err);
334       g_free (debug);
335
336       printf ("presse <ENTER> key to exit\n");
337       exit_read = 1;
338       g_main_loop_quit (loop);
339       break;
340     case GST_MESSAGE_EOS:
341       /* end-of-stream */
342       printf ("presse any key to exit\n");
343       exit_read = 1;
344       g_main_loop_quit (loop);
345       break;
346     default:
347       break;
348     }
349   }
350   return TRUE;
351 }
352
353 int
354 main (int argc, char *argv[])
355 {
356
357   GThread *input_thread;
358   gint numbuffers = -1;
359   gchar device[128] = { '\0' };
360   gchar input[128] = { '\0' };
361   gulong frequency = 0;
362   GstBus *bus;
363
364   /* see for input option */
365
366   int c;
367
368   while (1) {
369     static char long_options_desc[][64] = {
370       {"Number of buffers to output before sending EOS"},
371       {"Device location. Common in /dev/video0"},
372       {"input/output (channel) to switch to"},
373       {"frequency to tune to (in Hz)"},
374       {0, 0, 0, 0}
375     };
376     static struct option long_options[] = {
377       {"numbuffers", 1, 0, 'n'},
378       {"device", 1, 0, 'd'},
379       {"input", 1, 0, 'i'},
380       {"frequency", 1, 0, 'f'},
381       {0, 0, 0, 0}
382     };
383     /* getopt_long stores the option index here. */
384     int option_index = 0;
385
386     c = getopt_long (argc, argv, "n:d:i:f:h", long_options, &option_index);
387
388     /* Detect the end of the options. */
389     if (c == -1) {
390       printf ("tip: use -h to see help message.\n");
391       break;
392     }
393
394     switch (c) {
395       case 0:
396         /* If this option set a flag, do nothing else now. */
397         if (long_options[option_index].flag != 0)
398           break;
399         printf ("option %s", long_options[option_index].name);
400         if (optarg)
401           printf (" with arg %s", optarg);
402         printf ("\n");
403         break;
404
405       case 'n':
406         numbuffers = atoi (optarg);
407         break;
408
409       case 'd':
410         strncpy (device, optarg, sizeof (device) / sizeof (device[0]));
411         break;
412
413       case 'i':
414         strncpy (input, optarg, sizeof (input) / sizeof (input[0]));
415         break;
416
417       case 'f':
418         frequency = atol (optarg);
419         break;
420
421       case 'h':
422         printf ("Usage: v4l2src-test [OPTION]...\n");
423         for (c = 0; long_options[c].name; ++c) {
424           printf ("-%c, --%s\r\t\t\t\t%s\n", long_options[c].val,
425               long_options[c].name, long_options_desc[c]);
426         }
427         exit (0);
428         break;
429
430       case '?':
431         /* getopt_long already printed an error message. */
432         printf ("Use -h to see help message.\n");
433         break;
434
435       default:
436         abort ();
437     }
438   }
439
440   /* Print any remaining command line arguments (not options). */
441   if (optind < argc) {
442     printf ("Use -h to see help message.\n" "non-option ARGV-elements: ");
443     while (optind < argc)
444       printf ("%s ", argv[optind++]);
445     putchar ('\n');
446   }
447
448   /* init */
449   gst_init (&argc, &argv);
450
451   /* create elements */
452   if (!(pipeline = gst_pipeline_new ("my_pipeline"))) {
453     fprintf (stderr, "error: gst_pipeline_new return NULL");
454     return -1;
455   }
456
457   if (!(source = gst_element_factory_make ("v4l2src", NULL))) {
458     fprintf (stderr,
459         "error: gst_element_factory_make (\"v4l2src\", NULL) return NULL");
460     return -1;
461   }
462
463   if (!(sink = gst_element_factory_make ("xvimagesink", NULL))) {
464     fprintf (stderr,
465         "error: gst_element_factory_make (\"xvimagesink\", NULL) return NULL");
466     return -1;
467   }
468
469   if (numbuffers > -1) {
470     g_object_set (source, "num-buffers", numbuffers, NULL);
471   }
472   if (device[0]) {
473     g_object_set (source, "device", device, NULL);
474   }
475   if (input[0]) {
476     g_object_set (source, "input", input, NULL);
477   }
478   if (frequency) {
479     g_object_set (source, "frequency", frequency, NULL);
480   }
481
482   /* you would normally check that the elements were created properly */
483   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
484   gst_bus_add_watch (bus, my_bus_callback, NULL);
485
486   /* put together a pipeline */
487   gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
488   gst_element_link_pads (source, "src", sink, "sink");
489
490   /* start the pipeline */
491   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
492   loop = g_main_loop_new (NULL, FALSE);
493
494 #if !GLIB_CHECK_VERSION (2, 31, 0)
495   input_thread = g_thread_create (read_user, source, TRUE, NULL);
496 #else
497   input_thread = g_thread_try_new ("v4l2src-test", read_user, source, NULL);
498 #endif
499
500   if (input_thread == NULL) {
501     fprintf (stderr, "error: g_thread_create return NULL");
502     return -1;
503   }
504
505   g_main_loop_run (loop);
506   g_thread_join (input_thread);
507
508   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
509
510   gst_object_unref (bus);
511   gst_object_unref (pipeline);
512
513   gst_deinit ();
514
515   return 0;
516
517 }