/* GStreamer * * Copyright (C) 2015 Samsung Electronics. All rights reserved. * Author: Thiago Santos * * 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. */ /* demo for showing v4l2src renegotiating */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* Options */ static const gchar *device = "/dev/video0"; static const gchar *videosink = "autovideosink"; static gboolean enable_dmabuf = FALSE; static const gchar *def_resolutions[] = { "320x240", "1280x720", "640x480", NULL }; static const gchar **resolutions = def_resolutions; static GOptionEntry entries[] = { {"device", 'd', 0, G_OPTION_ARG_STRING, &device, "V4L2 Camera Device", NULL}, {"videosink", 's', 0, G_OPTION_ARG_STRING, &videosink, "Video Sink to use", NULL}, {"enable-dmabuf", 'z', 0, G_OPTION_ARG_NONE, &enable_dmabuf, "Enable DMABuf", NULL}, {"resolution", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &resolutions, "Add a resolution to the list", NULL}, {NULL} }; static GMainLoop *loop; static GstElement *pipeline; static GstElement *src, *capsfilter; static gint index = 0; static gboolean bus_callback (GstBus * bus, GstMessage * message, gpointer data) { switch (message->type) { case GST_MESSAGE_EOS: g_main_loop_quit (loop); break; case GST_MESSAGE_ERROR:{ GError *gerror; gchar *debug; gst_message_parse_error (message, &gerror, &debug); gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); g_error_free (gerror); g_free (debug); g_main_loop_quit (loop); break; } default: break; } return TRUE; } static gboolean change_caps (gpointer data) { GstCaps *caps; GStrv res; gchar *caps_str; if (!resolutions[index]) { gst_element_send_event (pipeline, gst_event_new_eos ()); return FALSE; } g_print ("Setting resolution to '%s'\n", resolutions[index]); res = g_strsplit (resolutions[index++], "x", 2); if (!res[0] || !res[1]) { g_warning ("Can't parse resolution: %s", resolutions[index - 1]); g_strfreev (res); return TRUE; } caps_str = g_strdup_printf ("video/x-raw,width=%s,height=%s", res[0], res[1]); caps = gst_caps_from_string (caps_str); g_object_set (capsfilter, "caps", caps, NULL); g_strfreev (res); g_free (caps_str); gst_caps_unref (caps); return TRUE; } gint main (gint argc, gchar ** argv) { GstBus *bus; GError *error = NULL; GOptionContext *context; gchar *desc; context = g_option_context_new ("- test v4l2src live renegotition"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); g_option_context_add_group (context, gst_init_get_option_group ()); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_print ("option parsing failed: %s\n", error->message); g_error_free (error); return 1; } loop = g_main_loop_new (NULL, FALSE); desc = g_strdup_printf ("v4l2src name=src device=\"%s\" io-mode=\"%s\" " "! capsfilter name=cf ! %s", device, enable_dmabuf ? "dmabuf" : "mmap", videosink); pipeline = gst_parse_launch (desc, &error); if (!pipeline) { g_print ("failed to create pipeline: %s", error->message); g_error_free (error); return 1; } src = gst_bin_get_by_name (GST_BIN (pipeline), "src"); capsfilter = gst_bin_get_by_name (GST_BIN (pipeline), "cf"); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, bus_callback, NULL); gst_object_unref (bus); change_caps (NULL); /* play and wait */ gst_element_set_state (pipeline, GST_STATE_PLAYING); g_timeout_add_seconds (3, change_caps, NULL); /* mainloop and wait for eos */ g_main_loop_run (loop); /* stop and cleanup */ gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (src); gst_object_unref (capsfilter); gst_object_unref (GST_OBJECT (pipeline)); g_main_loop_unref (loop); return 0; }