gst_plugins_base/sys/v4l/gstv4ltuner.c
branchRCL_3
changeset 30 7e817e7e631c
parent 0 0e761a78d257
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
       
     1 /* GStreamer
       
     2  *
       
     3  * gstv4ltuner.c: tuner interface implementation for V4L
       
     4  *
       
     5  * Copyright (C) 2003 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 <gst/gst.h>
       
    28 
       
    29 #include "gstv4ltuner.h"
       
    30 #include "gstv4lelement.h"
       
    31 #include "v4l_calls.h"
       
    32 
       
    33 static void gst_v4l_tuner_channel_class_init (GstV4lTunerChannelClass * klass);
       
    34 static void gst_v4l_tuner_channel_init (GstV4lTunerChannel * channel);
       
    35 
       
    36 static void gst_v4l_tuner_norm_class_init (GstV4lTunerNormClass * klass);
       
    37 static void gst_v4l_tuner_norm_init (GstV4lTunerNorm * norm);
       
    38 
       
    39 static const GList *gst_v4l_tuner_list_channels (GstTuner * tuner);
       
    40 static void gst_v4l_tuner_set_channel (GstTuner * tuner,
       
    41     GstTunerChannel * channel);
       
    42 static GstTunerChannel *gst_v4l_tuner_get_channel (GstTuner * tuner);
       
    43 
       
    44 static const GList *gst_v4l_tuner_list_norms (GstTuner * tuner);
       
    45 static void gst_v4l_tuner_set_norm (GstTuner * tuner, GstTunerNorm * norm);
       
    46 static GstTunerNorm *gst_v4l_tuner_get_norm (GstTuner * tuner);
       
    47 
       
    48 static void gst_v4l_tuner_set_frequency (GstTuner * tuner,
       
    49     GstTunerChannel * channel, gulong frequency);
       
    50 static gulong gst_v4l_tuner_get_frequency (GstTuner * tuner,
       
    51     GstTunerChannel * channel);
       
    52 static gint gst_v4l_tuner_signal_strength (GstTuner * tuner,
       
    53     GstTunerChannel * channel);
       
    54 
       
    55 static GstTunerNormClass *norm_parent_class = NULL;
       
    56 static GstTunerChannelClass *channel_parent_class = NULL;
       
    57 
       
    58 GType
       
    59 gst_v4l_tuner_channel_get_type (void)
       
    60 {
       
    61   static GType gst_v4l_tuner_channel_type = 0;
       
    62 
       
    63   if (!gst_v4l_tuner_channel_type) {
       
    64     static const GTypeInfo v4l_tuner_channel_info = {
       
    65       sizeof (GstV4lTunerChannelClass),
       
    66       NULL,
       
    67       NULL,
       
    68       (GClassInitFunc) gst_v4l_tuner_channel_class_init,
       
    69       NULL,
       
    70       NULL,
       
    71       sizeof (GstV4lTunerChannel),
       
    72       0,
       
    73       (GInstanceInitFunc) gst_v4l_tuner_channel_init,
       
    74       NULL
       
    75     };
       
    76 
       
    77     gst_v4l_tuner_channel_type =
       
    78         g_type_register_static (GST_TYPE_TUNER_CHANNEL,
       
    79         "GstV4lTunerChannel", &v4l_tuner_channel_info, 0);
       
    80   }
       
    81 
       
    82   return gst_v4l_tuner_channel_type;
       
    83 }
       
    84 
       
    85 static void
       
    86 gst_v4l_tuner_channel_class_init (GstV4lTunerChannelClass * klass)
       
    87 {
       
    88   channel_parent_class = g_type_class_peek_parent (klass);
       
    89 }
       
    90 
       
    91 static void
       
    92 gst_v4l_tuner_channel_init (GstV4lTunerChannel * channel)
       
    93 {
       
    94   channel->index = 0;
       
    95   channel->audio = 0;
       
    96   channel->tuner = 0;
       
    97 }
       
    98 
       
    99 GType
       
   100 gst_v4l_tuner_norm_get_type (void)
       
   101 {
       
   102   static GType gst_v4l_tuner_norm_type = 0;
       
   103 
       
   104   if (!gst_v4l_tuner_norm_type) {
       
   105     static const GTypeInfo v4l_tuner_norm_info = {
       
   106       sizeof (GstV4lTunerNormClass),
       
   107       NULL,
       
   108       NULL,
       
   109       (GClassInitFunc) gst_v4l_tuner_norm_class_init,
       
   110       NULL,
       
   111       NULL,
       
   112       sizeof (GstV4lTunerNorm),
       
   113       0,
       
   114       (GInstanceInitFunc) gst_v4l_tuner_norm_init,
       
   115       NULL
       
   116     };
       
   117 
       
   118     gst_v4l_tuner_norm_type =
       
   119         g_type_register_static (GST_TYPE_TUNER_NORM,
       
   120         "GstV4lTunerNorm", &v4l_tuner_norm_info, 0);
       
   121   }
       
   122 
       
   123   return gst_v4l_tuner_norm_type;
       
   124 }
       
   125 
       
   126 static void
       
   127 gst_v4l_tuner_norm_class_init (GstV4lTunerNormClass * klass)
       
   128 {
       
   129   norm_parent_class = g_type_class_peek_parent (klass);
       
   130 }
       
   131 
       
   132 static void
       
   133 gst_v4l_tuner_norm_init (GstV4lTunerNorm * norm)
       
   134 {
       
   135   norm->index = 0;
       
   136 }
       
   137 
       
   138 void
       
   139 gst_v4l_tuner_interface_init (GstTunerClass * klass)
       
   140 {
       
   141   /* default virtual functions */
       
   142   klass->list_channels = gst_v4l_tuner_list_channels;
       
   143   klass->set_channel = gst_v4l_tuner_set_channel;
       
   144   klass->get_channel = gst_v4l_tuner_get_channel;
       
   145 
       
   146   klass->list_norms = gst_v4l_tuner_list_norms;
       
   147   klass->set_norm = gst_v4l_tuner_set_norm;
       
   148   klass->get_norm = gst_v4l_tuner_get_norm;
       
   149 
       
   150   klass->set_frequency = gst_v4l_tuner_set_frequency;
       
   151   klass->get_frequency = gst_v4l_tuner_get_frequency;
       
   152   klass->signal_strength = gst_v4l_tuner_signal_strength;
       
   153 }
       
   154 
       
   155 static G_GNUC_UNUSED gboolean
       
   156 gst_v4l_tuner_contains_channel (GstV4lElement * v4lelement,
       
   157     GstV4lTunerChannel * v4lchannel)
       
   158 {
       
   159   const GList *item;
       
   160 
       
   161   for (item = v4lelement->channels; item != NULL; item = item->next)
       
   162     if (item->data == v4lchannel)
       
   163       return TRUE;
       
   164 
       
   165   return FALSE;
       
   166 }
       
   167 
       
   168 static const GList *
       
   169 gst_v4l_tuner_list_channels (GstTuner * tuner)
       
   170 {
       
   171   return GST_V4LELEMENT (tuner)->channels;
       
   172 }
       
   173 
       
   174 static void
       
   175 gst_v4l_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel)
       
   176 {
       
   177   GstV4lElement *v4lelement = GST_V4LELEMENT (tuner);
       
   178   GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel);
       
   179   gint norm;
       
   180 
       
   181   /* assert that we're opened and that we're using a known item */
       
   182   g_return_if_fail (GST_V4L_IS_OPEN (v4lelement));
       
   183   g_return_if_fail (gst_v4l_tuner_contains_channel (v4lelement, v4lchannel));
       
   184 
       
   185   gst_v4l_get_chan_norm (v4lelement, NULL, &norm);
       
   186   gst_v4l_set_chan_norm (v4lelement, v4lchannel->index, norm);
       
   187 }
       
   188 
       
   189 static GstTunerChannel *
       
   190 gst_v4l_tuner_get_channel (GstTuner * tuner)
       
   191 {
       
   192   GstV4lElement *v4lelement = GST_V4LELEMENT (tuner);
       
   193   GList *item;
       
   194   gint channel;
       
   195 
       
   196   /* assert that we're opened */
       
   197   g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), NULL);
       
   198 
       
   199   gst_v4l_get_chan_norm (v4lelement, &channel, NULL);
       
   200 
       
   201   for (item = v4lelement->channels; item != NULL; item = item->next) {
       
   202     if (channel == GST_V4L_TUNER_CHANNEL (item->data)->index)
       
   203       return GST_TUNER_CHANNEL (item->data);
       
   204   }
       
   205 
       
   206   return NULL;
       
   207 }
       
   208 
       
   209 static G_GNUC_UNUSED gboolean
       
   210 gst_v4l_tuner_contains_norm (GstV4lElement * v4lelement,
       
   211     GstV4lTunerNorm * v4lnorm)
       
   212 {
       
   213   const GList *item;
       
   214 
       
   215   for (item = v4lelement->norms; item != NULL; item = item->next)
       
   216     if (item->data == v4lnorm)
       
   217       return TRUE;
       
   218 
       
   219   return FALSE;
       
   220 }
       
   221 
       
   222 static const GList *
       
   223 gst_v4l_tuner_list_norms (GstTuner * tuner)
       
   224 {
       
   225   return GST_V4LELEMENT (tuner)->norms;
       
   226 }
       
   227 
       
   228 static void
       
   229 gst_v4l_tuner_set_norm (GstTuner * tuner, GstTunerNorm * norm)
       
   230 {
       
   231   GstV4lElement *v4lelement = GST_V4LELEMENT (tuner);
       
   232   GstV4lTunerNorm *v4lnorm = GST_V4L_TUNER_NORM (norm);
       
   233   gint channel;
       
   234 
       
   235   /* assert that we're opened and that we're using a known item */
       
   236   g_return_if_fail (GST_V4L_IS_OPEN (v4lelement));
       
   237   g_return_if_fail (gst_v4l_tuner_contains_norm (v4lelement, v4lnorm));
       
   238 
       
   239   gst_v4l_get_chan_norm (v4lelement, &channel, NULL);
       
   240   gst_v4l_set_chan_norm (v4lelement, channel, v4lnorm->index);
       
   241 }
       
   242 
       
   243 static GstTunerNorm *
       
   244 gst_v4l_tuner_get_norm (GstTuner * tuner)
       
   245 {
       
   246   GstV4lElement *v4lelement = GST_V4LELEMENT (tuner);
       
   247   GList *item;
       
   248   gint norm;
       
   249 
       
   250   /* assert that we're opened */
       
   251   g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), NULL);
       
   252 
       
   253   gst_v4l_get_chan_norm (v4lelement, NULL, &norm);
       
   254 
       
   255   for (item = v4lelement->norms; item != NULL; item = item->next) {
       
   256     if (norm == GST_V4L_TUNER_NORM (item->data)->index)
       
   257       return GST_TUNER_NORM (item->data);
       
   258   }
       
   259 
       
   260   return NULL;
       
   261 }
       
   262 
       
   263 static void
       
   264 gst_v4l_tuner_set_frequency (GstTuner * tuner,
       
   265     GstTunerChannel * channel, gulong frequency)
       
   266 {
       
   267   GstV4lElement *v4lelement = GST_V4LELEMENT (tuner);
       
   268   GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel);
       
   269   gint chan;
       
   270 
       
   271   /* assert that we're opened and that we're using a known item */
       
   272   g_return_if_fail (GST_V4L_IS_OPEN (v4lelement));
       
   273   g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
       
   274           GST_TUNER_CHANNEL_FREQUENCY));
       
   275   g_return_if_fail (gst_v4l_tuner_contains_channel (v4lelement, v4lchannel));
       
   276 
       
   277   gst_v4l_get_chan_norm (v4lelement, &chan, NULL);
       
   278   if (chan == GST_V4L_TUNER_CHANNEL (channel)->index) {
       
   279     gst_v4l_set_frequency (v4lelement, v4lchannel->tuner, frequency);
       
   280   }
       
   281 }
       
   282 
       
   283 static gulong
       
   284 gst_v4l_tuner_get_frequency (GstTuner * tuner, GstTunerChannel * channel)
       
   285 {
       
   286   GstV4lElement *v4lelement = GST_V4LELEMENT (tuner);
       
   287   GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel);
       
   288   gint chan;
       
   289   gulong frequency = 0;
       
   290 
       
   291   /* assert that we're opened and that we're using a known item */
       
   292   g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), 0);
       
   293   g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
       
   294           GST_TUNER_CHANNEL_FREQUENCY), 0);
       
   295   g_return_val_if_fail (gst_v4l_tuner_contains_channel (v4lelement,
       
   296           v4lchannel), 0);
       
   297 
       
   298   gst_v4l_get_chan_norm (v4lelement, &chan, NULL);
       
   299   if (chan == GST_V4L_TUNER_CHANNEL (channel)->index) {
       
   300     gst_v4l_get_frequency (v4lelement, v4lchannel->tuner, &frequency);
       
   301   }
       
   302 
       
   303   return frequency;
       
   304 }
       
   305 
       
   306 static gint
       
   307 gst_v4l_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel)
       
   308 {
       
   309   GstV4lElement *v4lelement = GST_V4LELEMENT (tuner);
       
   310   GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel);
       
   311   gint chan;
       
   312   guint signal = 0;
       
   313 
       
   314   /* assert that we're opened and that we're using a known item */
       
   315   g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), 0);
       
   316   g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
       
   317           GST_TUNER_CHANNEL_FREQUENCY), 0);
       
   318   g_return_val_if_fail (gst_v4l_tuner_contains_channel (v4lelement,
       
   319           v4lchannel), 0);
       
   320 
       
   321   gst_v4l_get_chan_norm (v4lelement, &chan, NULL);
       
   322   if (chan == GST_V4L_TUNER_CHANNEL (channel)->index &&
       
   323       GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
       
   324     gst_v4l_get_signal (v4lelement, v4lchannel->tuner, &signal);
       
   325   }
       
   326 
       
   327   return (gint) signal;
       
   328 }