diff options
Diffstat (limited to 'tests/icles/v4l2src-test.c')
-rwxr-xr-x | tests/icles/v4l2src-test.c | 514 |
1 files changed, 514 insertions, 0 deletions
diff --git a/tests/icles/v4l2src-test.c b/tests/icles/v4l2src-test.c new file mode 100755 index 0000000..2162e5c --- /dev/null +++ b/tests/icles/v4l2src-test.c @@ -0,0 +1,514 @@ +/* GStreamer + * + * Copyright (C) 2006 Edgard Lima <edgard dot lima at indt dot org dot br> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> + +#include <gst/gst.h> +#include <gst/video/colorbalance.h> +#include <gst/video/videoorientation.h> + +GstElement *pipeline, *source, *sink; +GMainLoop *loop; +volatile int exit_read = 0; + +static void +print_options (void) +{ + printf ("\nf - to change the fequency\n"); + printf ("i - to change the input\n"); + printf ("n - to change the norm\n"); + printf ("c - list color balance\n"); + printf ("v - change video orientarion\n"); + printf ("e - to exit\n"); +} + +static void +run_options (char opt) +{ + int res; + + switch (opt) { +#if 0 + case 'f': + { + GstTuner *tuner = GST_TUNER (source); + GstTunerChannel *channel; + guint freq; + + channel = gst_tuner_get_channel (tuner); + + freq = gst_tuner_get_frequency (tuner, channel); + + printf ("\ntype the new frequency (current = %u) (-1 to cancel): ", freq); + res = scanf ("%u", &freq); + if (res != 1 || freq != -1) + gst_tuner_set_frequency (tuner, channel, freq); + } + break; + case 'n': + { + GstTuner *tuner = GST_TUNER (source); + const GList *item, *list; + const GstTunerNorm *current_norm; + GstTunerNorm *norm = NULL; + gint index, next_norm; + + + list = gst_tuner_list_norms (tuner); + + current_norm = gst_tuner_get_norm (tuner); + + printf ("\nlist of norms:\n"); + for (item = list, index = 0; item != NULL; item = item->next, ++index) { + norm = item->data; + if (current_norm == norm) { + printf (" * %u - %s\n", index, norm->label); + } else { + printf (" %u - %s\n", index, norm->label); + } + } + printf ("\ntype the number of norm you want (-1 to cancel): "); + res = scanf ("%d", &next_norm); + if (res != 1 || next_norm < 0) { + break; + } + if (index <= next_norm) { + printf ("Norm %d not available\n", next_norm); + break; + } + for (item = list, index = 0; item != NULL && index <= next_norm; + item = item->next, ++index) { + norm = item->data; + } + if (norm) + gst_tuner_set_norm (tuner, norm); + } + break; + case 'i': + { + GstTuner *tuner = GST_TUNER (source); + const GList *item, *list; + const GstTunerChannel *current_channel; + GstTunerChannel *channel = NULL; + gint index, next_channel; + + + list = gst_tuner_list_channels (tuner); + + current_channel = gst_tuner_get_channel (tuner); + + printf ("\nlist of inputs:\n"); + for (item = list, index = 0; item != NULL; item = item->next, ++index) { + channel = item->data; + if (current_channel == channel) { + printf (" * %u - %s\n", index, channel->label); + } else { + printf (" %u - %s\n", index, channel->label); + } + } + printf ("\ntype the number of input you want (-1 to cancel): "); + res = scanf ("%d", &next_channel); + if (res != 1 || next_channel < 0) { + break; + } + if (index <= next_channel) { + printf ("Input %d not available\n", next_channel); + break; + } + for (item = list, index = 0; item != NULL && index <= next_channel; + item = item->next, ++index) { + channel = item->data; + } + if (channel) + gst_tuner_set_channel (tuner, channel); + } + break; +#endif + case 'e': + gst_element_set_state (pipeline, GST_STATE_NULL); + g_main_loop_quit (loop); + printf ("Bye\n"); + g_thread_exit (0); + break; + case 'c': + { + GstColorBalance *balance = GST_COLOR_BALANCE (source); + const GList *controls; + GstColorBalanceChannel *channel; + const GList *item; + gint index, new_value; + + controls = gst_color_balance_list_channels (balance); + + printf ("\n"); + + if (controls == NULL) { + printf ("There is no list of colorbalance controls\n"); + goto done; + } + + if (controls) { + printf ("list of controls:\n"); + for (item = controls, index = 0; item != NULL; + item = item->next, ++index) { + channel = item->data; + printf (" %u - %s (%d - %d) = %d\n", index, channel->label, + channel->min_value, channel->max_value, + gst_color_balance_get_value (balance, channel)); + } + printf ("\ntype the number of color control you want (-1 to cancel): "); + res = scanf ("%d", &new_value); + if (res != 1 || new_value == -1) + break; + for (item = controls, index = 0; item != NULL && index <= new_value; + item = item->next, ++index) { + channel = item->data; + } + printf (" %u - %s (%d - %d) = %d, type the new value: ", index - 1, + channel->label, channel->min_value, channel->max_value, + gst_color_balance_get_value (balance, channel)); + res = scanf ("%d", &new_value); + if (res != 1 || new_value == -1) + break; + gst_color_balance_set_value (balance, channel, new_value); + } + } + case 'v': + { + GstVideoOrientation *vidorient = GST_VIDEO_ORIENTATION (source); + gboolean flip = FALSE; + gint center = 0; + + printf ("\n"); + + if (gst_video_orientation_get_hflip (vidorient, &flip)) { + gint new_value; + + printf ("Horizontal flip is %s\n", flip ? "on" : "off"); + printf ("\ntype 1 to toggle (-1 to cancel): "); + res = scanf ("%d", &new_value); + if (res != 1 || new_value == 1) { + flip = !flip; + if (gst_video_orientation_set_hflip (vidorient, flip)) { + gst_video_orientation_get_hflip (vidorient, &flip); + printf ("Now horizontal flip is %s\n", flip ? "on" : "off"); + } else { + printf ("Error toggling horizontal flip\n"); + } + } else { + } + } else { + printf ("Horizontal flip control not available\n"); + } + + if (gst_video_orientation_get_vflip (vidorient, &flip)) { + gint new_value; + + printf ("\nVertical flip is %s\n", flip ? "on" : "off"); + printf ("\ntype 1 to toggle (-1 to cancel): "); + res = scanf ("%d", &new_value); + if (res != 1 || new_value == 1) { + flip = !flip; + if (gst_video_orientation_set_vflip (vidorient, flip)) { + gst_video_orientation_get_vflip (vidorient, &flip); + printf ("Now vertical flip is %s\n", flip ? "on" : "off"); + } else { + printf ("Error toggling vertical flip\n"); + } + } else { + } + } else { + printf ("Vertical flip control not available\n"); + } + + if (gst_video_orientation_get_hcenter (vidorient, ¢er)) { + printf ("Horizontal center is %d\n", center); + printf ("\ntype the new horizontal center value (-1 to cancel): "); + res = scanf ("%d", ¢er); + if (res != 1 || center != -1) { + if (gst_video_orientation_set_hcenter (vidorient, center)) { + gst_video_orientation_get_hcenter (vidorient, ¢er); + printf ("Now horizontal center is %d\n", center); + } else { + printf ("Error setting horizontal center\n"); + } + } else { + } + } else { + printf ("Horizontal center control not available\n"); + } + + if (gst_video_orientation_get_vcenter (vidorient, ¢er)) { + printf ("Vertical center is %d\n", center); + printf ("\ntype the new vertical center value (-1 to cancel): "); + res = scanf ("%d", ¢er); + if (res != 1 || center != -1) { + if (gst_video_orientation_set_vcenter (vidorient, center)) { + gst_video_orientation_get_vcenter (vidorient, ¢er); + printf ("Now vertical center is %d\n", center); + } else { + printf ("Error setting vertical center\n"); + } + } else { + } + } else { + printf ("Vertical center control not available\n"); + } + + } + break; + break; + default: + if (opt != 10) + printf ("error: invalid option %c", opt); + break; + } + +done: + + return; + +} + +static gpointer +read_user (gpointer data) +{ + + char opt; + + while (!exit_read) { + + print_options (); + + do { + opt = getchar (); + if (exit_read) { + break; + } + } while (opt == '\n'); + + run_options (opt); + + } + + return NULL; + +} + +static gboolean +my_bus_callback (GstBus * bus, GstMessage * message, gpointer data) +{ + + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_ERROR:{ + GError *err; + gchar *debug; + gchar *str; + + gst_message_parse_error (message, &err, &debug); + str = gst_element_get_name (message->src); + g_print ("%s error: %s\n", str, err->message); + g_free (str); + g_print ("Debug: %s\n", debug); + + g_error_free (err); + g_free (debug); + + printf ("presse <ENTER> key to exit\n"); + exit_read = 1; + g_main_loop_quit (loop); + break; + case GST_MESSAGE_EOS: + /* end-of-stream */ + printf ("presse any key to exit\n"); + exit_read = 1; + g_main_loop_quit (loop); + break; + default: + break; + } + } + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + + GThread *input_thread; + gint numbuffers = -1; + gchar device[128] = { '\0' }; + gchar input[128] = { '\0' }; + gulong frequency = 0; + GstBus *bus; + + /* see for input option */ + + int c; + + while (1) { + static char long_options_desc[][64] = { + {"Number of buffers to output before sending EOS"}, + {"Device location. Common in /dev/video0"}, + {"input/output (channel) to switch to"}, + {"frequency to tune to (in Hz)"}, + {0, 0, 0, 0} + }; + static struct option long_options[] = { + {"numbuffers", 1, 0, 'n'}, + {"device", 1, 0, 'd'}, + {"input", 1, 0, 'i'}, + {"frequency", 1, 0, 'f'}, + {0, 0, 0, 0} + }; + /* getopt_long stores the option index here. */ + int option_index = 0; + + c = getopt_long (argc, argv, "n:d:i:f:h", long_options, &option_index); + + /* Detect the end of the options. */ + if (c == -1) { + printf ("tip: use -h to see help message.\n"); + break; + } + + switch (c) { + case 0: + /* If this option set a flag, do nothing else now. */ + if (long_options[option_index].flag != 0) + break; + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case 'n': + numbuffers = atoi (optarg); + break; + + case 'd': + strncpy (device, optarg, sizeof (device) / sizeof (device[0])); + break; + + case 'i': + strncpy (input, optarg, sizeof (input) / sizeof (input[0])); + break; + + case 'f': + frequency = atol (optarg); + break; + + case 'h': + printf ("Usage: v4l2src-test [OPTION]...\n"); + for (c = 0; long_options[c].name; ++c) { + printf ("-%c, --%s\r\t\t\t\t%s\n", long_options[c].val, + long_options[c].name, long_options_desc[c]); + } + exit (0); + break; + + case '?': + /* getopt_long already printed an error message. */ + printf ("Use -h to see help message.\n"); + break; + + default: + abort (); + } + } + + /* Print any remaining command line arguments (not options). */ + if (optind < argc) { + printf ("Use -h to see help message.\n" "non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + putchar ('\n'); + } + + /* init */ + gst_init (&argc, &argv); + + /* create elements */ + if (!(pipeline = gst_pipeline_new ("my_pipeline"))) { + fprintf (stderr, "error: gst_pipeline_new return NULL"); + return -1; + } + + if (!(source = gst_element_factory_make ("v4l2src", NULL))) { + fprintf (stderr, + "error: gst_element_factory_make (\"v4l2src\", NULL) return NULL"); + return -1; + } + + if (!(sink = gst_element_factory_make ("xvimagesink", NULL))) { + fprintf (stderr, + "error: gst_element_factory_make (\"xvimagesink\", NULL) return NULL"); + return -1; + } + + if (numbuffers > -1) { + g_object_set (source, "num-buffers", numbuffers, NULL); + } + if (device[0]) { + g_object_set (source, "device", device, NULL); + } + if (input[0]) { + g_object_set (source, "input", input, NULL); + } + if (frequency) { + g_object_set (source, "frequency", frequency, NULL); + } + + /* you would normally check that the elements were created properly */ + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, my_bus_callback, NULL); + + /* put together a pipeline */ + gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); + gst_element_link_pads (source, "src", sink, "sink"); + + /* start the pipeline */ + gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); + loop = g_main_loop_new (NULL, FALSE); + + input_thread = g_thread_try_new ("v4l2src-test", read_user, source, NULL); + + if (input_thread == NULL) { + fprintf (stderr, "error: g_thread_try_new() failed"); + return -1; + } + + g_main_loop_run (loop); + g_thread_join (input_thread); + + gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); + + gst_object_unref (bus); + gst_object_unref (pipeline); + + gst_deinit (); + + return 0; + +} |