Unification of the way to speak to v4l2 and v4l elements... Also fix a segfautl when...
[platform/upstream/gstreamer.git] / sys / v4l2 / v4l2-overlay_calls.c
1 /* G-Streamer generic V4L2 element - generic V4L2 overlay handling
2  * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <sys/ioctl.h>
28 #include <sys/mman.h>
29 #include <string.h>
30 #include <errno.h>
31 #include "v4l2_calls.h"
32
33 #define DEBUG(format, args...) \
34         GST_DEBUG_ELEMENT(GST_CAT_PLUGIN_INFO, \
35                 GST_ELEMENT(v4l2element), \
36                 "V4L2-overlay: " format, ##args)
37
38
39 /******************************************************
40  * gst_v4l2_set_display():
41  *   calls v4l-conf
42  * return value: TRUE on success, FALSE on error
43  ******************************************************/
44
45 gboolean
46 gst_v4l2_set_display (GstV4l2Element *v4l2element,
47                       const gchar    *display)
48 {
49         gchar *buff;
50
51         DEBUG("trying to set overlay to '%s'", display);
52
53         /* start v4l-conf */
54         buff = g_strdup_printf("v4l-conf -q -c %s -d %s",
55                 v4l2element->device?v4l2element->device:"/dev/video", display);
56
57         switch (system(buff)) {
58                 case -1:
59                         gst_element_error(GST_ELEMENT(v4l2element),
60                                 "Could not start v4l-conf: %s", g_strerror(errno));
61                         g_free(buff);
62                         return FALSE;
63                 case 0:
64                         break;
65                 default:
66                         gst_element_error(GST_ELEMENT(v4l2element),
67                                 "v4l-conf failed to run correctly: %s", g_strerror(errno));
68                         g_free(buff);
69                         return FALSE;
70         }
71
72         g_free(buff);
73         return TRUE;
74 }
75
76
77 /******************************************************
78  * gst_v4l2_set_window():
79  *   sets the window where to display the video overlay
80  * return value: TRUE on success, FALSE on error
81  ******************************************************/
82
83 gboolean
84 gst_v4l2_set_window (GstElement       *element,
85                      gint              x,
86                      gint              y,
87                      gint              w,
88                      gint              h,
89                      struct v4l2_clip *clips,
90                      gint              num_clips)
91 {
92         struct v4l2_format fmt;
93         GstV4l2Element *v4l2element = GST_V4L2ELEMENT(element);
94
95         DEBUG("trying to set video window to %dx%d,%d,%d", x,y,w,h);
96         GST_V4L2_CHECK_OVERLAY(v4l2element);
97         GST_V4L2_CHECK_OPEN(v4l2element);
98
99         fmt.type = V4L2_CAP_VIDEO_OVERLAY;
100         fmt.fmt.win.clipcount = 0;
101         fmt.fmt.win.w.left = x;
102         fmt.fmt.win.w.top = y;
103         fmt.fmt.win.w.width = w;
104         fmt.fmt.win.w.height = h;
105         fmt.fmt.win.clips = clips;
106         fmt.fmt.win.clipcount = num_clips;
107         fmt.fmt.win.bitmap = NULL;
108
109         if (ioctl(v4l2element->video_fd, VIDIOC_S_FMT, &fmt) < 0) {
110                 gst_element_error(GST_ELEMENT(v4l2element),
111                         "Failed to set the video window on device %s: %s",
112                         v4l2element->device, g_strerror(errno));
113                 return FALSE;
114         }
115
116         return TRUE;
117 }
118
119
120 /******************************************************
121  * gst_v4l_set_overlay():
122  *   enables/disables actual video overlay display
123  * return value: TRUE on success, FALSE on error
124  ******************************************************/
125
126 gboolean
127 gst_v4l2_enable_overlay (GstV4l2Element *v4l2element,
128                          gboolean        enable)
129 {
130         gint doit = enable?1:0;
131
132         DEBUG("trying to %s overlay display", enable?"enable":"disable");
133         GST_V4L2_CHECK_OPEN(v4l2element);
134         GST_V4L2_CHECK_OVERLAY(v4l2element);
135
136         if (ioctl(v4l2element->video_fd, VIDIOC_OVERLAY, &doit) < 0) {
137                 gst_element_error(GST_ELEMENT(v4l2element),
138                         "Failed to %s overlay display for device %s: %s",
139                         enable?"enable":"disable", v4l2element->device, g_strerror(errno));
140                 return FALSE;
141         }
142
143         return TRUE;
144 }