Macro qtTrIdx() replaced by tr() and QT_TRANSLATE_NOOP()
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / sys / v4l / v4l_calls.c
1 /* GStreamer
2  *
3  * v4l_calls.c: generic V4L calls
4  *
5  * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31 #include <sys/mman.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <unistd.h>
35
36 #include <gst/gst.h>
37 #include <gst/interfaces/tuner.h>
38 #include <gst/interfaces/colorbalance.h>
39
40 #include "v4l_calls.h"
41 #include "gstv4ltuner.h"
42 #include "gstv4lcolorbalance.h"
43
44 #include "gstv4lsrc.h"
45 /* #include "gstv4lmjpegsrc.h" */
46 /* #include "gstv4lmjpegsink.h" */
47
48 GST_DEBUG_CATEGORY_EXTERN (v4l_debug);
49 #define GST_CAT_DEFAULT v4l_debug
50
51 static const char *picture_name[] = {
52   "Hue",
53   "Brightness",
54   "Contrast",
55   "Saturation",
56   NULL
57 };
58
59 G_GNUC_UNUSED static const char *audio_name[] = {
60   "Volume",
61   "Mute",
62   "Mode",
63   NULL
64 };
65
66 static const char *norm_name[] = {
67   "PAL",
68   "NTSC",
69   "SECAM",
70   NULL
71 };
72
73 /******************************************************
74  * gst_v4l_get_capabilities():
75  *   get the device's capturing capabilities
76  * sets v4lelement->vcap and v4lelement->vwin
77  * return value: TRUE on success, FALSE on error
78  ******************************************************/
79
80 gboolean
81 gst_v4l_get_capabilities (GstV4lElement * v4lelement)
82 {
83   GST_DEBUG_OBJECT (v4lelement, "getting capabilities");
84   GST_V4L_CHECK_OPEN (v4lelement);
85
86   if (ioctl (v4lelement->video_fd, VIDIOCGCAP, &(v4lelement->vcap)) < 0) {
87     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
88         ("error getting capabilities %s of from device %s",
89             g_strerror (errno), v4lelement->videodev));
90     return FALSE;
91   }
92
93   if (ioctl (v4lelement->video_fd, VIDIOCGWIN, &(v4lelement->vwin)) < 0) {
94     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
95         ("error getting window properties %s of from device %s",
96             g_strerror (errno), v4lelement->videodev));
97     return FALSE;
98   }
99
100   return TRUE;
101 }
102
103 /******************************************************
104  * gst_v4l_set_window_properties():
105  *   set the device's capturing parameters (vwin)
106  * return value: TRUE on success, FALSE on error
107  ******************************************************/
108
109 gboolean
110 gst_v4l_set_window_properties (GstV4lElement * v4lelement)
111 {
112   struct video_window vwin;
113
114   GST_DEBUG_OBJECT (v4lelement, "setting window flags 0x%x to device %s",
115       v4lelement->vwin.flags, v4lelement->videodev);
116   GST_V4L_CHECK_OPEN (v4lelement);
117
118   if (ioctl (v4lelement->video_fd, VIDIOCSWIN, &(v4lelement->vwin)) < 0) {
119     GST_DEBUG_OBJECT (v4lelement,
120         "could not ioctl window properties 0x%x to device %s",
121         v4lelement->vwin.flags, v4lelement->videodev);
122     return FALSE;
123   }
124
125   /* get it again to make sure we have it correctly */
126   if (ioctl (v4lelement->video_fd, VIDIOCGWIN, &(vwin)) < 0) {
127     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
128         ("error getting window properties %s of from device %s",
129             g_strerror (errno), v4lelement->videodev));
130     return FALSE;
131   }
132   if (vwin.flags != v4lelement->vwin.flags) {
133     GST_DEBUG_OBJECT (v4lelement, "set 0x%x but got 0x%x back",
134         v4lelement->vwin.flags, vwin.flags);
135     return FALSE;
136   }
137
138   return TRUE;
139 }
140
141 /******************************************************
142  * gst_v4l_open():
143  *   open the video device (v4lelement->videodev)
144  * return value: TRUE on success, FALSE on error
145  ******************************************************/
146
147 gboolean
148 gst_v4l_open (GstV4lElement * v4lelement)
149 {
150   int num;
151
152   GST_DEBUG_OBJECT (v4lelement, "opening device %s", v4lelement->videodev);
153   GST_V4L_CHECK_NOT_OPEN (v4lelement);
154   GST_V4L_CHECK_NOT_ACTIVE (v4lelement);
155
156   /* be sure we have a device */
157   if (!v4lelement->videodev) {
158     GST_ELEMENT_ERROR (v4lelement, RESOURCE, NOT_FOUND,
159         (_("No device specified.")), (NULL));
160     return FALSE;
161   }
162
163   /* open the device */
164   v4lelement->video_fd = open (v4lelement->videodev, O_RDWR);
165   if (!GST_V4L_IS_OPEN (v4lelement)) {
166     if (errno == ENODEV || errno == ENOENT) {
167       GST_ELEMENT_ERROR (v4lelement, RESOURCE, NOT_FOUND,
168           (_("Device \"%s\" does not exist."), v4lelement->videodev), (NULL));
169       return FALSE;
170     }
171     if (errno == EBUSY) {
172       GST_ELEMENT_ERROR (v4lelement, RESOURCE, BUSY,
173           (_("Device \"%s\" is already being used."), v4lelement->videodev),
174           (NULL));
175       return FALSE;
176     }
177     GST_ELEMENT_ERROR (v4lelement, RESOURCE, OPEN_READ_WRITE,
178         (_("Could not open device \"%s\" for reading and writing."),
179             v4lelement->videodev), GST_ERROR_SYSTEM);
180     return FALSE;
181   }
182
183   /* get capabilities */
184   if (!gst_v4l_get_capabilities (v4lelement)) {
185     close (v4lelement->video_fd);
186     v4lelement->video_fd = -1;
187     return FALSE;
188   }
189
190   /* device type check */
191   if ((GST_IS_V4LSRC (v4lelement) &&
192           !(v4lelement->vcap.type & VID_TYPE_CAPTURE))) {
193 /*       (GST_IS_V4LMJPEGSRC (v4lelement) && */
194 /*           !(v4lelement->vcap.type & VID_TYPE_MJPEG_ENCODER)) || */
195 /*       (GST_IS_V4LMJPEGSINK (v4lelement) && */
196 /*           !(v4lelement->vcap.type & VID_TYPE_MJPEG_DECODER))) { */
197     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
198         ("Device opened, but wrong type (0x%x)", v4lelement->vcap.type));
199     close (v4lelement->video_fd);
200     v4lelement->video_fd = -1;
201     return FALSE;
202   }
203
204   GST_INFO_OBJECT (v4lelement, "Opened device \'%s\' (\'%s\') successfully",
205       v4lelement->vcap.name, v4lelement->videodev);
206
207   /* norms + inputs, for the tuner interface */
208   for (num = 0; norm_name[num] != NULL; num++) {
209     GstV4lTunerNorm *v4lnorm = g_object_new (GST_TYPE_V4L_TUNER_NORM,
210         NULL);
211     GstTunerNorm *norm = GST_TUNER_NORM (v4lnorm);
212
213     norm->label = g_strdup (norm_name[num]);
214     if (num == 1)
215       gst_value_set_fraction (&norm->framerate, 30000, 1001);
216     else
217       gst_value_set_fraction (&norm->framerate, 25, 1);
218
219     v4lnorm->index = num;
220     v4lelement->norms = g_list_append (v4lelement->norms, (gpointer) norm);
221   }
222   v4lelement->channels = gst_v4l_get_chan_names (v4lelement);
223
224   for (num = 0; picture_name[num] != NULL; num++) {
225     GstV4lColorBalanceChannel *v4lchannel =
226         g_object_new (GST_TYPE_V4L_COLOR_BALANCE_CHANNEL, NULL);
227     GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (v4lchannel);
228
229     channel->label = g_strdup (picture_name[num]);
230     channel->min_value = 0;
231     channel->max_value = 65535;
232     v4lchannel->index = num;
233     v4lelement->colors = g_list_append (v4lelement->colors, channel);
234   }
235
236   GST_DEBUG_OBJECT (v4lelement, "Setting default norm/input");
237   gst_v4l_set_chan_norm (v4lelement, 0, 0);
238
239   return TRUE;
240 }
241
242
243 /******************************************************
244  * gst_v4l_close():
245  *   close the video device (v4lelement->video_fd)
246  * return value: TRUE on success, FALSE on error
247  ******************************************************/
248
249 gboolean
250 gst_v4l_close (GstV4lElement * v4lelement)
251 {
252   GST_DEBUG_OBJECT (v4lelement, "closing device");
253   GST_V4L_CHECK_OPEN (v4lelement);
254   GST_V4L_CHECK_NOT_ACTIVE (v4lelement);
255
256   close (v4lelement->video_fd);
257   v4lelement->video_fd = -1;
258
259   g_list_foreach (v4lelement->channels, (GFunc) g_object_unref, NULL);
260   g_list_free (v4lelement->channels);
261   v4lelement->channels = NULL;
262
263   g_list_foreach (v4lelement->norms, (GFunc) g_object_unref, NULL);
264   g_list_free (v4lelement->norms);
265   v4lelement->norms = NULL;
266
267   g_list_foreach (v4lelement->colors, (GFunc) g_object_unref, NULL);
268   g_list_free (v4lelement->colors);
269   v4lelement->colors = NULL;
270
271   return TRUE;
272 }
273
274
275 /******************************************************
276  * gst_v4l_get_num_chans()
277  * return value: the number of video input channels
278  ******************************************************/
279
280 static gint
281 gst_v4l_get_num_chans (GstV4lElement * v4lelement)
282 {
283   GST_DEBUG_OBJECT (v4lelement, "getting number of channels");
284   GST_V4L_CHECK_OPEN (v4lelement);
285
286   return v4lelement->vcap.channels;
287 }
288
289
290 /******************************************************
291  * gst_v4l_get_chan_names()
292  * return value: a GList containing the channel names
293  ******************************************************/
294
295 GList *
296 gst_v4l_get_chan_names (GstV4lElement * v4lelement)
297 {
298   struct video_channel vchan = { 0 };
299   GList *list = NULL;
300   gint i;
301
302   GST_DEBUG_OBJECT (v4lelement, "getting channel names");
303
304   if (!GST_V4L_IS_OPEN (v4lelement))
305     return NULL;
306
307   for (i = 0; i < gst_v4l_get_num_chans (v4lelement); i++) {
308     GstV4lTunerChannel *v4lchannel;
309     GstTunerChannel *channel;
310
311     vchan.channel = i;
312     if (ioctl (v4lelement->video_fd, VIDIOCGCHAN, &vchan) < 0) {
313       /* Skip this channel */
314       continue;
315     }
316     v4lchannel = g_object_new (GST_TYPE_V4L_TUNER_CHANNEL, NULL);
317     v4lchannel->index = i;
318
319     channel = GST_TUNER_CHANNEL (v4lchannel);
320     channel->label = g_strdup (vchan.name);
321     channel->flags = GST_TUNER_CHANNEL_INPUT;
322     if (vchan.flags & VIDEO_VC_TUNER) {
323       struct video_tuner vtun;
324       gint n;
325
326       for (n = 0; n < vchan.tuners; n++) {
327         vtun.tuner = n;
328         if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0)
329           continue;             /* no more tuners */
330         if (strcmp (vtun.name, vchan.name) != 0) {
331           continue;             /* not this one */
332         }
333
334         v4lchannel->tuner = n;
335         channel->flags |= GST_TUNER_CHANNEL_FREQUENCY;
336         channel->freq_multiplicator =
337             62.5 * ((vtun.flags & VIDEO_TUNER_LOW) ? 1 : 1000);
338         channel->min_frequency = vtun.rangelow * channel->freq_multiplicator;
339         channel->max_frequency = vtun.rangehigh * channel->freq_multiplicator;
340         channel->min_signal = 0;
341         channel->max_signal = 0xffff;
342         break;
343       }
344
345     }
346     if (vchan.flags & VIDEO_VC_AUDIO) {
347       struct video_audio vaud;
348       gint n;
349
350       for (n = 0; n < v4lelement->vcap.audios; n++) {
351         vaud.audio = n;
352         if (ioctl (v4lelement->video_fd, VIDIOCGAUDIO, &vaud) < 0)
353           continue;
354         if (!strcmp (vaud.name, vchan.name)) {
355           v4lchannel->audio = n;
356           channel->flags |= GST_TUNER_CHANNEL_AUDIO;
357           break;
358         }
359       }
360     }
361     list = g_list_prepend (list, (gpointer) channel);
362   }
363
364   return g_list_reverse (list);
365 }
366
367
368 /******************************************************
369  * gst_v4l_get_chan_norm():
370  *   get the currently active video-channel and it's
371  *   norm (VIDEO_MODE_{PAL|NTSC|SECAM|AUTO})
372  * return value: TRUE on success, FALSE on error
373  ******************************************************/
374
375 gboolean
376 gst_v4l_get_chan_norm (GstV4lElement * v4lelement, gint * channel, gint * norm)
377 {
378   GST_DEBUG_OBJECT (v4lelement, "getting current channel and norm");
379   GST_V4L_CHECK_OPEN (v4lelement);
380
381   if (channel)
382     *channel = v4lelement->vchan.channel;
383   if (norm)
384     *norm = v4lelement->vchan.norm;
385
386   return TRUE;
387 }
388
389
390 /******************************************************
391  * gst_v4l_set_chan_norm():
392  *   set a new active channel and it's norm
393  *   (VIDEO_MODE_{PAL|NTSC|SECAM|AUTO})
394  * return value: TRUE on success, FALSE on error
395  ******************************************************/
396
397 gboolean
398 gst_v4l_set_chan_norm (GstV4lElement * v4lelement, gint channel, gint norm)
399 {
400   GST_DEBUG_OBJECT (v4lelement, "setting channel = %d, norm = %d (%s)",
401       channel, norm, norm_name[norm]);
402   GST_V4L_CHECK_OPEN (v4lelement);
403   //GST_V4L_CHECK_NOT_ACTIVE (v4lelement);
404
405   v4lelement->vchan.channel = channel;
406   v4lelement->vchan.norm = norm;
407
408   if (ioctl (v4lelement->video_fd, VIDIOCSCHAN, &(v4lelement->vchan)) < 0) {
409     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
410         ("Error setting the channel/norm settings: %s", g_strerror (errno)));
411     return FALSE;
412   }
413
414   if (ioctl (v4lelement->video_fd, VIDIOCGCHAN, &(v4lelement->vchan)) < 0) {
415     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
416         ("Error getting the channel/norm settings: %s", g_strerror (errno)));
417     return FALSE;
418   }
419
420   return TRUE;
421 }
422
423
424 /******************************************************
425  * gst_v4l_get_signal():
426  *   get the current signal
427  * return value: TRUE on success, FALSE on error
428  ******************************************************/
429
430 gboolean
431 gst_v4l_get_signal (GstV4lElement * v4lelement, gint tunernum, guint * signal)
432 {
433   struct video_tuner tuner;
434
435   GST_DEBUG_OBJECT (v4lelement, "getting tuner signal");
436   GST_V4L_CHECK_OPEN (v4lelement);
437
438   tuner.tuner = tunernum;
439   if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &tuner) < 0) {
440     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
441         ("Error getting tuner signal: %s", g_strerror (errno)));
442     return FALSE;
443   }
444
445   *signal = tuner.signal;
446
447   return TRUE;
448 }
449
450
451 /******************************************************
452  * gst_v4l_get_frequency():
453  *   get the current frequency
454  * return value: TRUE on success, FALSE on error
455  ******************************************************/
456
457 gboolean
458 gst_v4l_get_frequency (GstV4lElement * v4lelement,
459     gint tunernum, gulong * frequency)
460 {
461   struct video_tuner vtun;
462   GstTunerChannel *channel;
463
464   GST_DEBUG_OBJECT (v4lelement, "getting tuner frequency");
465   GST_V4L_CHECK_OPEN (v4lelement);
466
467   channel = gst_tuner_get_channel (GST_TUNER (v4lelement));
468
469   /* check that this is the current input */
470   vtun.tuner = tunernum;
471   if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0)
472     return FALSE;
473   if (strcmp (vtun.name, v4lelement->vchan.name))
474     return FALSE;
475
476   if (ioctl (v4lelement->video_fd, VIDIOCGFREQ, frequency) < 0) {
477     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
478         ("Error getting tuner frequency: %s", g_strerror (errno)));
479     return FALSE;
480   }
481
482   *frequency = *frequency * channel->freq_multiplicator;
483
484   return TRUE;
485 }
486
487
488 /******************************************************
489  * gst_v4l_set_frequency():
490  *   set frequency
491  * return value: TRUE on success, FALSE on error
492  ******************************************************/
493
494 gboolean
495 gst_v4l_set_frequency (GstV4lElement * v4lelement,
496     gint tunernum, gulong frequency)
497 {
498   struct video_tuner vtun;
499   GstTunerChannel *channel;
500
501   GST_DEBUG_OBJECT (v4lelement, "setting tuner frequency to %lu", frequency);
502   GST_V4L_CHECK_OPEN (v4lelement);
503
504   channel = gst_tuner_get_channel (GST_TUNER (v4lelement));
505
506   /* check that this is the current input */
507   vtun.tuner = tunernum;
508   if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0)
509     return FALSE;
510   if (strcmp (vtun.name, v4lelement->vchan.name))
511     return FALSE;
512
513   frequency = frequency / channel->freq_multiplicator;
514
515   if (ioctl (v4lelement->video_fd, VIDIOCSFREQ, &frequency) < 0) {
516     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
517         ("Error setting tuner frequency: %s", g_strerror (errno)));
518     return FALSE;
519   }
520
521   return TRUE;
522 }
523
524
525 /******************************************************
526  * gst_v4l_get_picture():
527  *   get a picture value
528  * return value: TRUE on success, FALSE on error
529  ******************************************************/
530
531 gboolean
532 gst_v4l_get_picture (GstV4lElement * v4lelement,
533     GstV4lPictureType type, gint * value)
534 {
535   struct video_picture vpic;
536
537   GST_DEBUG_OBJECT (v4lelement, "getting picture property type %d (%s)", type,
538       picture_name[type]);
539   GST_V4L_CHECK_OPEN (v4lelement);
540
541   if (ioctl (v4lelement->video_fd, VIDIOCGPICT, &vpic) < 0) {
542     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
543         ("Error getting picture parameters: %s", g_strerror (errno)));
544     return FALSE;
545   }
546
547   switch (type) {
548     case V4L_PICTURE_HUE:
549       *value = vpic.hue;
550       break;
551     case V4L_PICTURE_BRIGHTNESS:
552       *value = vpic.brightness;
553       break;
554     case V4L_PICTURE_CONTRAST:
555       *value = vpic.contrast;
556       break;
557     case V4L_PICTURE_SATURATION:
558       *value = vpic.colour;
559       break;
560     default:
561       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
562           ("Error getting picture parameters: unknown type %d", type));
563       return FALSE;
564   }
565
566   return TRUE;
567 }
568
569
570 /******************************************************
571  * gst_v4l_set_picture():
572  *   set a picture value
573  * return value: TRUE on success, FALSE on error
574  ******************************************************/
575
576 gboolean
577 gst_v4l_set_picture (GstV4lElement * v4lelement,
578     GstV4lPictureType type, gint value)
579 {
580   struct video_picture vpic;
581
582   GST_DEBUG_OBJECT (v4lelement, "setting picture type %d (%s) to value %d",
583       type, picture_name[type], value);
584   GST_V4L_CHECK_OPEN (v4lelement);
585
586   if (ioctl (v4lelement->video_fd, VIDIOCGPICT, &vpic) < 0) {
587     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
588         ("Error getting picture parameters: %s", g_strerror (errno)));
589     return FALSE;
590   }
591
592   switch (type) {
593     case V4L_PICTURE_HUE:
594       vpic.hue = value;
595       break;
596     case V4L_PICTURE_BRIGHTNESS:
597       vpic.brightness = value;
598       break;
599     case V4L_PICTURE_CONTRAST:
600       vpic.contrast = value;
601       break;
602     case V4L_PICTURE_SATURATION:
603       vpic.colour = value;
604       break;
605     default:
606       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
607           ("Error setting picture parameters: unknown type %d", type));
608       return FALSE;
609   }
610
611   if (ioctl (v4lelement->video_fd, VIDIOCSPICT, &vpic) < 0) {
612     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
613         ("Error setting picture parameters: %s", g_strerror (errno)));
614     return FALSE;
615   }
616
617   return TRUE;
618 }
619
620
621 /******************************************************
622  * gst_v4l_get_audio():
623  *   get some audio value
624  * return value: TRUE on success, FALSE on error
625  ******************************************************/
626
627 gboolean
628 gst_v4l_get_audio (GstV4lElement * v4lelement,
629     gint audionum, GstV4lAudioType type, gint * value)
630 {
631   struct video_audio vau;
632
633   GST_DEBUG_OBJECT (v4lelement, "getting audio parameter type %d (%s)", type,
634       audio_name[type]);
635   GST_V4L_CHECK_OPEN (v4lelement);
636
637   vau.audio = audionum;
638   if (ioctl (v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0) {
639     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
640         ("Error getting audio parameters: %s", g_strerror (errno)));
641     return FALSE;
642   }
643
644   switch (type) {
645     case V4L_AUDIO_MUTE:
646       *value = (vau.flags & VIDEO_AUDIO_MUTE);
647       break;
648     case V4L_AUDIO_VOLUME:
649       *value = vau.volume;
650       break;
651     case V4L_AUDIO_MODE:
652       *value = vau.mode;
653       break;
654     default:
655       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
656           ("Error getting audio parameters: unknown type %d", type));
657       return FALSE;
658   }
659
660   return TRUE;
661 }
662
663
664 /******************************************************
665  * gst_v4l_set_audio():
666  *   set some audio value
667  * return value: TRUE on success, FALSE on error
668  ******************************************************/
669
670 gboolean
671 gst_v4l_set_audio (GstV4lElement * v4lelement,
672     gint audionum, GstV4lAudioType type, gint value)
673 {
674   struct video_audio vau;
675
676   GST_DEBUG_OBJECT (v4lelement,
677       "setting audio parameter type %d (%s) to value %d", type,
678       audio_name[type], value);
679   GST_V4L_CHECK_OPEN (v4lelement);
680
681   vau.audio = audionum;
682   if (ioctl (v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0) {
683     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
684         ("Error getting audio parameters: %s", g_strerror (errno)));
685     return FALSE;
686   }
687
688   switch (type) {
689     case V4L_AUDIO_MUTE:
690       if (!(vau.flags & VIDEO_AUDIO_MUTABLE)) {
691         GST_ELEMENT_ERROR (v4lelement, CORE, NOT_IMPLEMENTED, (NULL),
692             ("Error setting audio mute: (un)setting mute is not supported"));
693         return FALSE;
694       }
695       if (value)
696         vau.flags |= VIDEO_AUDIO_MUTE;
697       else
698         vau.flags &= ~VIDEO_AUDIO_MUTE;
699       break;
700     case V4L_AUDIO_VOLUME:
701       if (!(vau.flags & VIDEO_AUDIO_VOLUME)) {
702         GST_ELEMENT_ERROR (v4lelement, CORE, NOT_IMPLEMENTED, (NULL),
703             ("Error setting audio volume: setting volume is not supported"));
704         return FALSE;
705       }
706       vau.volume = value;
707       break;
708     case V4L_AUDIO_MODE:
709       vau.mode = value;
710       break;
711     default:
712       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
713           ("Error setting audio parameters: unknown type %d", type));
714       return FALSE;
715   }
716
717   if (ioctl (v4lelement->video_fd, VIDIOCSAUDIO, &vau) < 0) {
718     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
719         ("Error setting audio parameters: %s", g_strerror (errno)));
720     return FALSE;
721   }
722
723   return TRUE;
724 }