1 /* G-Streamer generic V4L element - generic V4L calls handling
2 * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
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.
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.
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.
22 #include <sys/types.h>
25 #include <sys/ioctl.h>
29 #include "v4l_calls.h"
32 char *picture_name[] = { "Hue", "Brightness", "Contrast", "Saturation", NULL };
34 char *audio_name[] = { "Volume", "Mute", "Mode", NULL };
36 char *norm_name[] = { "PAL", "NTSC", "SECAM", NULL };
38 /******************************************************
39 * gst_v4l_get_capabilities():
40 * get the device's capturing capabilities
41 * return value: TRUE on success, FALSE on error
42 ******************************************************/
45 gst_v4l_get_capabilities (GstV4lElement *v4lelement)
48 fprintf(stderr, "V4L: gst_v4l_get_capabilities()\n");
51 GST_V4L_CHECK_OPEN(v4lelement);
53 if (ioctl(v4lelement->video_fd, VIDIOCGCAP, &(v4lelement->vcap)) < 0)
55 gst_element_error(GST_ELEMENT(v4lelement),
56 "Error getting \'%s\' capabilities: %s",
57 v4lelement->videodev, sys_errlist[errno]);
65 /******************************************************
67 * open the video device (v4lelement->videodev)
68 * return value: TRUE on success, FALSE on error
69 ******************************************************/
72 gst_v4l_open (GstV4lElement *v4lelement)
75 fprintf(stderr, "V4L: gst_v4l_open()\n");
78 GST_V4L_CHECK_NOT_OPEN(v4lelement);
79 GST_V4L_CHECK_NOT_ACTIVE(v4lelement);
81 /* be sure we have a device */
82 if (!v4lelement->videodev)
83 v4lelement->videodev = g_strdup("/dev/video");
86 v4lelement->video_fd = open(v4lelement->videodev, O_RDWR);
87 if (!GST_V4L_IS_OPEN(v4lelement))
89 gst_element_error(GST_ELEMENT(v4lelement),
90 "Failed to open device (\'%s\'): %s",
91 v4lelement->videodev, sys_errlist[errno]);
95 /* get capabilities */
96 if (!gst_v4l_get_capabilities(v4lelement))
98 close(v4lelement->video_fd);
99 v4lelement->video_fd = -1;
103 gst_info("Opened device \'%s\' (\'%s\') successfully\n",
104 v4lelement->vcap.name, v4lelement->videodev);
110 /******************************************************
112 * close the video device (v4lelement->video_fd)
113 * return value: TRUE on success, FALSE on error
114 ******************************************************/
117 gst_v4l_close (GstV4lElement *v4lelement)
120 fprintf(stderr, "V4L: gst_v4l_close()\n");
123 GST_V4L_CHECK_OPEN(v4lelement);
124 GST_V4L_CHECK_NOT_ACTIVE(v4lelement);
126 close(v4lelement->video_fd);
127 v4lelement->video_fd = -1;
133 /******************************************************
134 * gst_v4l_get_num_chans()
135 * return value: the numver of video input channels
136 ******************************************************/
139 gst_v4l_get_num_chans (GstV4lElement *v4lelement)
142 fprintf(stderr, "V4L: gst_v4l_get_num_chans()\n");
145 GST_V4L_CHECK_OPEN(v4lelement);
147 return v4lelement->vcap.channels;
151 /******************************************************
152 * gst_v4l_get_chan_names()
153 * return value: a GList containing the channel names
154 ******************************************************/
157 gst_v4l_get_chan_names (GstV4lElement *v4lelement)
159 struct video_channel vchan;
164 fprintf(stderr, "V4L: gst_v4l_get_chan_names()\n");
167 if (!GST_V4L_IS_OPEN(v4lelement))
170 for (i=0;i<gst_v4l_get_num_chans(v4lelement);i++)
173 if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &vchan) < 0)
175 list = g_list_append(list, (gpointer)g_strdup(vchan.name));
182 /******************************************************
183 * gst_v4l_get_chan_norm():
184 * get the currently active video-channel and it's
185 * norm (VIDEO_MODE_{PAL|NTSC|SECAM|AUTO})
186 * return value: TRUE on success, FALSE on error
187 ******************************************************/
190 gst_v4l_get_chan_norm (GstV4lElement *v4lelement,
195 fprintf(stderr, "V4L: gst_v4l_get_chan_norm()\n");
198 GST_V4L_CHECK_OPEN(v4lelement);
201 *channel = v4lelement->vchan.channel;
203 *norm = v4lelement->vchan.norm;
209 /******************************************************
210 * gst_v4l_set_chan_norm():
211 * set a new active channel and it's norm
212 * (VIDEO_MODE_{PAL|NTSC|SECAM|AUTO})
213 * return value: TRUE on success, FALSE on error
214 ******************************************************/
217 gst_v4l_set_chan_norm (GstV4lElement *v4lelement,
222 fprintf(stderr, "V4L: gst_v4l_set_chan_norm(), channel = %d, norm = %d (%s)\n",
223 channel, norm, norm_name[norm]);
226 GST_V4L_CHECK_OPEN(v4lelement);
227 GST_V4L_CHECK_NOT_ACTIVE(v4lelement);
229 v4lelement->vchan.channel = channel;
230 v4lelement->vchan.norm = norm;
232 if (ioctl(v4lelement->video_fd, VIDIOCSCHAN, &(v4lelement->vchan)) < 0)
234 gst_element_error(GST_ELEMENT(v4lelement),
235 "Error setting the channel/norm settings: %s",
240 if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &(v4lelement->vchan)) < 0)
242 gst_element_error(GST_ELEMENT(v4lelement),
243 "Error getting the channel/norm settings: %s",
252 /******************************************************
253 * gst_v4l_has_tuner():
254 * return value: TRUE if it has a tuner, else FALSE
255 ******************************************************/
258 gst_v4l_has_tuner (GstV4lElement *v4lelement)
261 fprintf(stderr, "V4L: gst_v4l_has_tuner()\n");
264 GST_V4L_CHECK_OPEN(v4lelement);
266 return (v4lelement->vcap.type & VID_TYPE_TUNER &&
267 v4lelement->vchan.flags & VIDEO_VC_TUNER);
271 /******************************************************
272 * gst_v4l_get_frequency():
273 * get the current frequency
274 * return value: TRUE on success, FALSE on error
275 ******************************************************/
278 gst_v4l_get_frequency (GstV4lElement *v4lelement,
282 fprintf(stderr, "V4L: gst_v4l_get_frequency()\n");
285 GST_V4L_CHECK_OPEN(v4lelement);
287 if (!gst_v4l_has_tuner(v4lelement))
290 if (ioctl(v4lelement->video_fd, VIDIOCGFREQ, frequency) < 0)
292 gst_element_error(GST_ELEMENT(v4lelement),
293 "Error getting tuner frequency: %s",
302 /******************************************************
303 * gst_v4l_set_frequency():
305 * return value: TRUE on success, FALSE on error
306 ******************************************************/
309 gst_v4l_set_frequency (GstV4lElement *v4lelement,
313 fprintf(stderr, "gst_v4l_set_frequency(), frequency = %ul\n",
317 GST_V4L_CHECK_OPEN(v4lelement);
318 GST_V4L_CHECK_NOT_ACTIVE(v4lelement);
320 if (!gst_v4l_has_tuner(v4lelement))
323 if (ioctl(v4lelement->video_fd, VIDIOCSFREQ, &frequency) < 0)
325 gst_element_error(GST_ELEMENT(v4lelement),
326 "Error setting tuner frequency: %s",
335 /******************************************************
336 * gst_v4l_get_picture():
337 * get a picture value
338 * return value: TRUE on success, FALSE on error
339 ******************************************************/
342 gst_v4l_get_picture (GstV4lElement *v4lelement,
343 GstV4lPictureType type,
346 struct video_picture vpic;
349 fprintf(stderr, "V4L: gst_v4l_get_picture(), type = %d (%s)\n",
350 type, picture_name[type]);
353 GST_V4L_CHECK_OPEN(v4lelement);
355 if (ioctl(v4lelement->video_fd, VIDIOCGPICT, &vpic) < 0)
357 gst_element_error(GST_ELEMENT(v4lelement),
358 "Error getting picture parameters: %s",
365 case V4L_PICTURE_HUE:
368 case V4L_PICTURE_BRIGHTNESS:
369 *value = vpic.brightness;
371 case V4L_PICTURE_CONTRAST:
372 *value = vpic.contrast;
374 case V4L_PICTURE_SATURATION:
375 *value = vpic.colour;
378 gst_element_error(GST_ELEMENT(v4lelement),
379 "Error getting picture parameters: unknown type %d",
388 /******************************************************
389 * gst_v4l_set_picture():
390 * set a picture value
391 * return value: TRUE on success, FALSE on error
392 ******************************************************/
395 gst_v4l_set_picture (GstV4lElement *v4lelement,
396 GstV4lPictureType type,
399 struct video_picture vpic;
402 fprintf(stderr, "V4L: gst_v4l_set_picture(), type = %d (%s), value = %d\n",
403 type, picture_name[type], value);
406 GST_V4L_CHECK_OPEN(v4lelement);
408 if (ioctl(v4lelement->video_fd, VIDIOCGPICT, &vpic) < 0)
410 gst_element_error(GST_ELEMENT(v4lelement),
411 "Error getting picture parameters: %s",
418 case V4L_PICTURE_HUE:
421 case V4L_PICTURE_BRIGHTNESS:
422 vpic.brightness = value;
424 case V4L_PICTURE_CONTRAST:
425 vpic.contrast = value;
427 case V4L_PICTURE_SATURATION:
431 gst_element_error(GST_ELEMENT(v4lelement),
432 "Error setting picture parameters: unknown type %d",
437 if (ioctl(v4lelement->video_fd, VIDIOCSPICT, &vpic) < 0)
439 gst_element_error(GST_ELEMENT(v4lelement),
440 "Error setting picture parameters: %s",
449 /******************************************************
450 * gst_v4l_has_audio():
451 * return value: TRUE if it can do audio, else FALSE
452 ******************************************************/
455 gst_v4l_has_audio (GstV4lElement *v4lelement)
458 fprintf(stderr, "V4L: gst_v4l_has_audio()\n");
461 GST_V4L_CHECK_OPEN(v4lelement);
463 return (v4lelement->vcap.audios > 0 &&
464 v4lelement->vchan.flags & VIDEO_VC_AUDIO);
468 /******************************************************
469 * gst_v4l_get_audio():
470 * get some audio value
471 * return value: TRUE on success, FALSE on error
472 ******************************************************/
475 gst_v4l_get_audio (GstV4lElement *v4lelement,
476 GstV4lAudioType type,
479 struct video_audio vau;
482 fprintf(stderr, "V4L: v4l_gst_get_audio(), type = %d (%s)\n",
483 type, audio_name[type]);
486 GST_V4L_CHECK_OPEN(v4lelement);
488 if (!gst_v4l_has_audio(v4lelement))
491 if (ioctl(v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0)
493 gst_element_error(GST_ELEMENT(v4lelement),
494 "Error getting audio parameters: %s",
502 *value = (vau.flags & VIDEO_AUDIO_MUTE);
504 case V4L_AUDIO_VOLUME:
511 gst_element_error(GST_ELEMENT(v4lelement),
512 "Error getting audio parameters: unknown type %d",
521 /******************************************************
522 * gst_v4l_set_audio():
523 * set some audio value
524 * return value: TRUE on success, FALSE on error
525 ******************************************************/
528 gst_v4l_set_audio (GstV4lElement *v4lelement,
529 GstV4lAudioType type,
532 struct video_audio vau;
535 fprintf(stderr, "V4L: v4l_gst_set_audio(), type = %d (%s), value = %d\n",
536 type, audio_name[type], value);
539 GST_V4L_CHECK_OPEN(v4lelement);
541 if (!gst_v4l_has_audio(v4lelement))
544 if (ioctl(v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0)
546 gst_element_error(GST_ELEMENT(v4lelement),
547 "Error getting audio parameters: %s",
555 if (!(vau.flags & VIDEO_AUDIO_MUTABLE))
557 gst_element_error(GST_ELEMENT(v4lelement),
558 "Error setting audio mute: (un)setting mute is not supported");
562 vau.flags |= VIDEO_AUDIO_MUTE;
564 vau.flags &= ~VIDEO_AUDIO_MUTE;
566 case V4L_AUDIO_VOLUME:
567 if (!(vau.flags & VIDEO_AUDIO_VOLUME))
569 gst_element_error(GST_ELEMENT(v4lelement),
570 "Error setting audio volume: setting volume is not supported");
579 gst_element_error(GST_ELEMENT(v4lelement),
580 "Error setting audio parameters: unknown type %d",
585 if (ioctl(v4lelement->video_fd, VIDIOCSAUDIO, &vau) < 0)
587 gst_element_error(GST_ELEMENT(v4lelement),
588 "Error setting audio parameters: %s",