gst_plugins_base/sys/v4l/v4l_calls.c
branchRCL_3
changeset 29 567bb019e3e3
parent 6 9b2c3c7a1a9c
child 30 7e817e7e631c
equal deleted inserted replaced
6:9b2c3c7a1a9c 29:567bb019e3e3
     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;
       
   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 = g_object_new (GST_TYPE_V4L_TUNER_CHANNEL,
       
   309         NULL);
       
   310     GstTunerChannel *channel = GST_TUNER_CHANNEL (v4lchannel);
       
   311 
       
   312     vchan.channel = i;
       
   313     if (ioctl (v4lelement->video_fd, VIDIOCGCHAN, &vchan) < 0)
       
   314       return NULL;              /* memleak... */
       
   315     channel->label = g_strdup (vchan.name);
       
   316     channel->flags = GST_TUNER_CHANNEL_INPUT;
       
   317     v4lchannel->index = i;
       
   318     if (vchan.flags & VIDEO_VC_TUNER) {
       
   319       struct video_tuner vtun;
       
   320       gint n;
       
   321 
       
   322       for (n = 0;; n++) {
       
   323         if (n >= vchan.tuners) {
       
   324           vtun.tuner = 0;       /* default */
       
   325         } else {
       
   326           vtun.tuner = n;
       
   327           if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0)
       
   328             continue;           /* no more tuners */
       
   329           if (strcmp (vtun.name, vchan.name) != 0) {
       
   330             continue;           /* not this one */
       
   331           }
       
   332         }
       
   333         v4lchannel->tuner = n;
       
   334         channel->flags |= GST_TUNER_CHANNEL_FREQUENCY;
       
   335         channel->freq_multiplicator =
       
   336             62.5 * ((vtun.flags & VIDEO_TUNER_LOW) ? 1 : 1000);
       
   337         channel->min_frequency = vtun.rangelow;
       
   338         channel->max_frequency = vtun.rangehigh;
       
   339         channel->min_signal = 0;
       
   340         channel->max_signal = 0xffff;
       
   341         break;
       
   342       }
       
   343 
       
   344     }
       
   345     if (vchan.flags & VIDEO_VC_AUDIO) {
       
   346       struct video_audio vaud;
       
   347       gint n;
       
   348 
       
   349       for (n = 0; n < v4lelement->vcap.audios; n++) {
       
   350         vaud.audio = n;
       
   351         if (ioctl (v4lelement->video_fd, VIDIOCGAUDIO, &vaud) < 0)
       
   352           continue;
       
   353         if (!strcmp (vaud.name, vchan.name)) {
       
   354           v4lchannel->audio = n;
       
   355           channel->flags |= GST_TUNER_CHANNEL_AUDIO;
       
   356           break;
       
   357         }
       
   358       }
       
   359     }
       
   360     list = g_list_append (list, (gpointer) channel);
       
   361   }
       
   362 
       
   363   return list;
       
   364 }
       
   365 
       
   366 
       
   367 /******************************************************
       
   368  * gst_v4l_get_chan_norm():
       
   369  *   get the currently active video-channel and it's
       
   370  *   norm (VIDEO_MODE_{PAL|NTSC|SECAM|AUTO})
       
   371  * return value: TRUE on success, FALSE on error
       
   372  ******************************************************/
       
   373 
       
   374 gboolean
       
   375 gst_v4l_get_chan_norm (GstV4lElement * v4lelement, gint * channel, gint * norm)
       
   376 {
       
   377   GST_DEBUG_OBJECT (v4lelement, "getting current channel and norm");
       
   378   GST_V4L_CHECK_OPEN (v4lelement);
       
   379 
       
   380   if (channel)
       
   381     *channel = v4lelement->vchan.channel;
       
   382   if (norm)
       
   383     *norm = v4lelement->vchan.norm;
       
   384 
       
   385   return TRUE;
       
   386 }
       
   387 
       
   388 
       
   389 /******************************************************
       
   390  * gst_v4l_set_chan_norm():
       
   391  *   set a new active channel and it's norm
       
   392  *   (VIDEO_MODE_{PAL|NTSC|SECAM|AUTO})
       
   393  * return value: TRUE on success, FALSE on error
       
   394  ******************************************************/
       
   395 
       
   396 gboolean
       
   397 gst_v4l_set_chan_norm (GstV4lElement * v4lelement, gint channel, gint norm)
       
   398 {
       
   399   GST_DEBUG_OBJECT (v4lelement, "setting channel = %d, norm = %d (%s)",
       
   400       channel, norm, norm_name[norm]);
       
   401   GST_V4L_CHECK_OPEN (v4lelement);
       
   402   //GST_V4L_CHECK_NOT_ACTIVE (v4lelement);
       
   403 
       
   404   v4lelement->vchan.channel = channel;
       
   405   v4lelement->vchan.norm = norm;
       
   406 
       
   407   if (ioctl (v4lelement->video_fd, VIDIOCSCHAN, &(v4lelement->vchan)) < 0) {
       
   408     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   409         ("Error setting the channel/norm settings: %s", g_strerror (errno)));
       
   410     return FALSE;
       
   411   }
       
   412 
       
   413   if (ioctl (v4lelement->video_fd, VIDIOCGCHAN, &(v4lelement->vchan)) < 0) {
       
   414     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   415         ("Error getting the channel/norm settings: %s", g_strerror (errno)));
       
   416     return FALSE;
       
   417   }
       
   418 
       
   419   return TRUE;
       
   420 }
       
   421 
       
   422 
       
   423 /******************************************************
       
   424  * gst_v4l_get_signal():
       
   425  *   get the current signal
       
   426  * return value: TRUE on success, FALSE on error
       
   427  ******************************************************/
       
   428 
       
   429 gboolean
       
   430 gst_v4l_get_signal (GstV4lElement * v4lelement, gint tunernum, guint * signal)
       
   431 {
       
   432   struct video_tuner tuner;
       
   433 
       
   434   GST_DEBUG_OBJECT (v4lelement, "getting tuner signal");
       
   435   GST_V4L_CHECK_OPEN (v4lelement);
       
   436 
       
   437   tuner.tuner = tunernum;
       
   438   if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &tuner) < 0) {
       
   439     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   440         ("Error getting tuner signal: %s", g_strerror (errno)));
       
   441     return FALSE;
       
   442   }
       
   443 
       
   444   *signal = tuner.signal;
       
   445 
       
   446   return TRUE;
       
   447 }
       
   448 
       
   449 
       
   450 /******************************************************
       
   451  * gst_v4l_get_frequency():
       
   452  *   get the current frequency
       
   453  * return value: TRUE on success, FALSE on error
       
   454  ******************************************************/
       
   455 
       
   456 gboolean
       
   457 gst_v4l_get_frequency (GstV4lElement * v4lelement,
       
   458     gint tunernum, gulong * frequency)
       
   459 {
       
   460   struct video_tuner vtun;
       
   461   GstTunerChannel *channel;
       
   462 
       
   463   GST_DEBUG_OBJECT (v4lelement, "getting tuner frequency");
       
   464   GST_V4L_CHECK_OPEN (v4lelement);
       
   465 
       
   466   channel = gst_tuner_get_channel (GST_TUNER (v4lelement));
       
   467 
       
   468   /* check that this is the current input */
       
   469   vtun.tuner = tunernum;
       
   470   if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0)
       
   471     return FALSE;
       
   472   if (strcmp (vtun.name, v4lelement->vchan.name))
       
   473     return FALSE;
       
   474 
       
   475   if (ioctl (v4lelement->video_fd, VIDIOCGFREQ, frequency) < 0) {
       
   476     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   477         ("Error getting tuner frequency: %s", g_strerror (errno)));
       
   478     return FALSE;
       
   479   }
       
   480 
       
   481   *frequency = *frequency * channel->freq_multiplicator;
       
   482 
       
   483   return TRUE;
       
   484 }
       
   485 
       
   486 
       
   487 /******************************************************
       
   488  * gst_v4l_set_frequency():
       
   489  *   set frequency
       
   490  * return value: TRUE on success, FALSE on error
       
   491  ******************************************************/
       
   492 
       
   493 gboolean
       
   494 gst_v4l_set_frequency (GstV4lElement * v4lelement,
       
   495     gint tunernum, gulong frequency)
       
   496 {
       
   497   struct video_tuner vtun;
       
   498   GstTunerChannel *channel;
       
   499 
       
   500   GST_DEBUG_OBJECT (v4lelement, "setting tuner frequency to %lu", frequency);
       
   501   GST_V4L_CHECK_OPEN (v4lelement);
       
   502 
       
   503   channel = gst_tuner_get_channel (GST_TUNER (v4lelement));
       
   504 
       
   505   /* check that this is the current input */
       
   506   vtun.tuner = tunernum;
       
   507   if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0)
       
   508     return FALSE;
       
   509   if (strcmp (vtun.name, v4lelement->vchan.name))
       
   510     return FALSE;
       
   511 
       
   512   frequency = frequency / channel->freq_multiplicator;
       
   513 
       
   514   if (ioctl (v4lelement->video_fd, VIDIOCSFREQ, &frequency) < 0) {
       
   515     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   516         ("Error setting tuner frequency: %s", g_strerror (errno)));
       
   517     return FALSE;
       
   518   }
       
   519 
       
   520   return TRUE;
       
   521 }
       
   522 
       
   523 
       
   524 /******************************************************
       
   525  * gst_v4l_get_picture():
       
   526  *   get a picture value
       
   527  * return value: TRUE on success, FALSE on error
       
   528  ******************************************************/
       
   529 
       
   530 gboolean
       
   531 gst_v4l_get_picture (GstV4lElement * v4lelement,
       
   532     GstV4lPictureType type, gint * value)
       
   533 {
       
   534   struct video_picture vpic;
       
   535 
       
   536   GST_DEBUG_OBJECT (v4lelement, "getting picture property type %d (%s)", type,
       
   537       picture_name[type]);
       
   538   GST_V4L_CHECK_OPEN (v4lelement);
       
   539 
       
   540   if (ioctl (v4lelement->video_fd, VIDIOCGPICT, &vpic) < 0) {
       
   541     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   542         ("Error getting picture parameters: %s", g_strerror (errno)));
       
   543     return FALSE;
       
   544   }
       
   545 
       
   546   switch (type) {
       
   547     case V4L_PICTURE_HUE:
       
   548       *value = vpic.hue;
       
   549       break;
       
   550     case V4L_PICTURE_BRIGHTNESS:
       
   551       *value = vpic.brightness;
       
   552       break;
       
   553     case V4L_PICTURE_CONTRAST:
       
   554       *value = vpic.contrast;
       
   555       break;
       
   556     case V4L_PICTURE_SATURATION:
       
   557       *value = vpic.colour;
       
   558       break;
       
   559     default:
       
   560       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   561           ("Error getting picture parameters: unknown type %d", type));
       
   562       return FALSE;
       
   563   }
       
   564 
       
   565   return TRUE;
       
   566 }
       
   567 
       
   568 
       
   569 /******************************************************
       
   570  * gst_v4l_set_picture():
       
   571  *   set a picture value
       
   572  * return value: TRUE on success, FALSE on error
       
   573  ******************************************************/
       
   574 
       
   575 gboolean
       
   576 gst_v4l_set_picture (GstV4lElement * v4lelement,
       
   577     GstV4lPictureType type, gint value)
       
   578 {
       
   579   struct video_picture vpic;
       
   580 
       
   581   GST_DEBUG_OBJECT (v4lelement, "setting picture type %d (%s) to value %d",
       
   582       type, picture_name[type], value);
       
   583   GST_V4L_CHECK_OPEN (v4lelement);
       
   584 
       
   585   if (ioctl (v4lelement->video_fd, VIDIOCGPICT, &vpic) < 0) {
       
   586     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   587         ("Error getting picture parameters: %s", g_strerror (errno)));
       
   588     return FALSE;
       
   589   }
       
   590 
       
   591   switch (type) {
       
   592     case V4L_PICTURE_HUE:
       
   593       vpic.hue = value;
       
   594       break;
       
   595     case V4L_PICTURE_BRIGHTNESS:
       
   596       vpic.brightness = value;
       
   597       break;
       
   598     case V4L_PICTURE_CONTRAST:
       
   599       vpic.contrast = value;
       
   600       break;
       
   601     case V4L_PICTURE_SATURATION:
       
   602       vpic.colour = value;
       
   603       break;
       
   604     default:
       
   605       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   606           ("Error setting picture parameters: unknown type %d", type));
       
   607       return FALSE;
       
   608   }
       
   609 
       
   610   if (ioctl (v4lelement->video_fd, VIDIOCSPICT, &vpic) < 0) {
       
   611     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   612         ("Error setting picture parameters: %s", g_strerror (errno)));
       
   613     return FALSE;
       
   614   }
       
   615 
       
   616   return TRUE;
       
   617 }
       
   618 
       
   619 
       
   620 /******************************************************
       
   621  * gst_v4l_get_audio():
       
   622  *   get some audio value
       
   623  * return value: TRUE on success, FALSE on error
       
   624  ******************************************************/
       
   625 
       
   626 gboolean
       
   627 gst_v4l_get_audio (GstV4lElement * v4lelement,
       
   628     gint audionum, GstV4lAudioType type, gint * value)
       
   629 {
       
   630   struct video_audio vau;
       
   631 
       
   632   GST_DEBUG_OBJECT (v4lelement, "getting audio parameter type %d (%s)", type,
       
   633       audio_name[type]);
       
   634   GST_V4L_CHECK_OPEN (v4lelement);
       
   635 
       
   636   vau.audio = audionum;
       
   637   if (ioctl (v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0) {
       
   638     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   639         ("Error getting audio parameters: %s", g_strerror (errno)));
       
   640     return FALSE;
       
   641   }
       
   642 
       
   643   switch (type) {
       
   644     case V4L_AUDIO_MUTE:
       
   645       *value = (vau.flags & VIDEO_AUDIO_MUTE);
       
   646       break;
       
   647     case V4L_AUDIO_VOLUME:
       
   648       *value = vau.volume;
       
   649       break;
       
   650     case V4L_AUDIO_MODE:
       
   651       *value = vau.mode;
       
   652       break;
       
   653     default:
       
   654       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   655           ("Error getting audio parameters: unknown type %d", type));
       
   656       return FALSE;
       
   657   }
       
   658 
       
   659   return TRUE;
       
   660 }
       
   661 
       
   662 
       
   663 /******************************************************
       
   664  * gst_v4l_set_audio():
       
   665  *   set some audio value
       
   666  * return value: TRUE on success, FALSE on error
       
   667  ******************************************************/
       
   668 
       
   669 gboolean
       
   670 gst_v4l_set_audio (GstV4lElement * v4lelement,
       
   671     gint audionum, GstV4lAudioType type, gint value)
       
   672 {
       
   673   struct video_audio vau;
       
   674 
       
   675   GST_DEBUG_OBJECT (v4lelement,
       
   676       "setting audio parameter type %d (%s) to value %d", type,
       
   677       audio_name[type], value);
       
   678   GST_V4L_CHECK_OPEN (v4lelement);
       
   679 
       
   680   vau.audio = audionum;
       
   681   if (ioctl (v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0) {
       
   682     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   683         ("Error getting audio parameters: %s", g_strerror (errno)));
       
   684     return FALSE;
       
   685   }
       
   686 
       
   687   switch (type) {
       
   688     case V4L_AUDIO_MUTE:
       
   689       if (!(vau.flags & VIDEO_AUDIO_MUTABLE)) {
       
   690         GST_ELEMENT_ERROR (v4lelement, CORE, NOT_IMPLEMENTED, (NULL),
       
   691             ("Error setting audio mute: (un)setting mute is not supported"));
       
   692         return FALSE;
       
   693       }
       
   694       if (value)
       
   695         vau.flags |= VIDEO_AUDIO_MUTE;
       
   696       else
       
   697         vau.flags &= ~VIDEO_AUDIO_MUTE;
       
   698       break;
       
   699     case V4L_AUDIO_VOLUME:
       
   700       if (!(vau.flags & VIDEO_AUDIO_VOLUME)) {
       
   701         GST_ELEMENT_ERROR (v4lelement, CORE, NOT_IMPLEMENTED, (NULL),
       
   702             ("Error setting audio volume: setting volume is not supported"));
       
   703         return FALSE;
       
   704       }
       
   705       vau.volume = value;
       
   706       break;
       
   707     case V4L_AUDIO_MODE:
       
   708       vau.mode = value;
       
   709       break;
       
   710     default:
       
   711       GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   712           ("Error setting audio parameters: unknown type %d", type));
       
   713       return FALSE;
       
   714   }
       
   715 
       
   716   if (ioctl (v4lelement->video_fd, VIDIOCSAUDIO, &vau) < 0) {
       
   717     GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
       
   718         ("Error setting audio parameters: %s", g_strerror (errno)));
       
   719     return FALSE;
       
   720   }
       
   721 
       
   722   return TRUE;
       
   723 }