2 * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
4 * tuner.c: tuner design virtual class function wrappers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
32 * @short_description: Interface for elements providing tuner operations
36 * The GstTuner interface is provided by elements that have the ability to
37 * tune into multiple input signals, for example TV or radio capture cards.
39 * The interpretation of 'tuning into' an input stream depends on the element
40 * implementing the interface. For v4lsrc, it might imply selection of an
41 * input source and/or frequency to be configured on a TV card. Another
42 * GstTuner implementation might be to allow selection of an active input pad
43 * from multiple input pads.
45 * That said, the GstTuner interface functions are biased toward the
46 * TV capture scenario.
48 * The general parameters provided are for configuration are:
50 * <listitem>Selection of a current #GstTunerChannel. The current channel
51 * represents the input source (e.g. Composite, S-Video etc for TV capture).
53 * <listitem>The #GstTunerNorm for the channel. The norm chooses the
54 * interpretation of the incoming signal for the current channel. For example,
55 * PAL or NTSC, or more specific variants there-of.
57 * <listitem>Channel frequency. If the current channel has the ability to tune
58 * between multiple frequencies (if it has the GST_TUNER_CHANNEL_FREQUENCY flag)
59 * then the frequency can be changed/retrieved via the
60 * gst_tuner_set_frequency() and gst_tuner_get_frequency() methods.
65 * Where applicable, the signal strength can be retrieved and/or monitored
71 /* FIXME 0.11: check if we need to add API for sometimes-supportedness
72 * (aka making up for GstImplementsInterface removal) */
74 /* FIXME 0.11: replace signals with messages (+ make API thread-safe) */
85 static guint gst_tuner_signals[LAST_SIGNAL] = { 0 };
87 G_DEFINE_INTERFACE (GstTuner, gst_tuner, G_TYPE_INVALID);
90 gst_tuner_default_init (GstTunerInterface * iface)
92 static gboolean initialized = FALSE;
96 * GstTuner::norm-changed:
97 * @tuner: The element providing the GstTuner interface
98 * @norm: The new configured norm.
100 * Reports that the current #GstTunerNorm has changed.
102 gst_tuner_signals[NORM_CHANGED] =
103 g_signal_new ("norm-changed",
104 GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
105 G_STRUCT_OFFSET (GstTunerInterface, norm_changed),
107 g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_TUNER_NORM);
109 * GstTuner::channel-changed:
110 * @tuner: The element providing the GstTuner interface
111 * @channel: The new configured channel.
113 * Reports that the current #GstTunerChannel has changed.
115 gst_tuner_signals[CHANNEL_CHANGED] =
116 g_signal_new ("channel-changed",
117 GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
118 G_STRUCT_OFFSET (GstTunerInterface, channel_changed),
120 g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
121 GST_TYPE_TUNER_CHANNEL);
123 * GstTuner::frequency-changed:
124 * @tuner: The element providing the GstTuner interface
125 * @frequency: The new frequency (an unsigned long)
127 * Reports that the current frequency has changed.
129 gst_tuner_signals[FREQUENCY_CHANGED] =
130 g_signal_new ("frequency-changed",
131 GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
132 G_STRUCT_OFFSET (GstTunerInterface, frequency_changed),
134 g_cclosure_marshal_generic, G_TYPE_NONE, 2, GST_TYPE_TUNER_CHANNEL,
137 * GstTuner::signal-changed:
138 * @tuner: The element providing the GstTuner interface
139 * @channel: The current #GstTunerChannel
140 * @signal: The new signal strength (an integer)
142 * Reports that the signal strength has changed.
144 * See Also: gst_tuner_signal_strength()
146 gst_tuner_signals[SIGNAL_CHANGED] =
147 g_signal_new ("signal-changed",
148 GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
149 G_STRUCT_OFFSET (GstTunerInterface, signal_changed),
151 g_cclosure_marshal_generic, G_TYPE_NONE, 2, GST_TYPE_TUNER_CHANNEL,
157 /* default virtual functions */
158 iface->list_channels = NULL;
159 iface->set_channel = NULL;
160 iface->get_channel = NULL;
162 iface->list_norms = NULL;
163 iface->set_norm = NULL;
164 iface->get_norm = NULL;
166 iface->set_frequency = NULL;
167 iface->get_frequency = NULL;
168 iface->signal_strength = NULL;
172 * gst_tuner_list_channels:
173 * @tuner: the #GstTuner (a #GstElement) to get the channels from.
175 * Retrieve a #GList of #GstTunerChannels available
176 * (e.g. 'composite', 's-video', ...) from the given tuner object.
178 * Returns: A list of channels available on this tuner. The list is
179 * owned by the GstTuner and must not be freed.
182 gst_tuner_list_channels (GstTuner * tuner)
184 GstTunerInterface *iface;
186 g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
188 iface = GST_TUNER_GET_INTERFACE (tuner);
189 if (iface->list_channels) {
190 return iface->list_channels (tuner);
197 * gst_tuner_set_channel:
198 * @tuner: the #GstTuner (a #GstElement) that owns the channel.
199 * @channel: the channel to tune to.
201 * Tunes the object to the given channel, which should be one of the
202 * channels returned by gst_tuner_list_channels().
206 gst_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel)
208 GstTunerInterface *iface;
210 g_return_if_fail (GST_IS_TUNER (tuner));
212 iface = GST_TUNER_GET_INTERFACE (tuner);
213 if (iface->set_channel) {
214 iface->set_channel (tuner, channel);
219 * gst_tuner_get_channel:
220 * @tuner: the #GstTuner (a #GstElement) to get the current channel from.
222 * Retrieve the current channel from the tuner.
224 * Returns: the current channel of the tuner object.
228 gst_tuner_get_channel (GstTuner * tuner)
230 GstTunerInterface *iface;
232 g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
234 iface = GST_TUNER_GET_INTERFACE (tuner);
235 if (iface->get_channel) {
236 return iface->get_channel (tuner);
243 * gst_tuner_list_norms:
244 * @tuner: the #GstTuner (*a #GstElement) to get the list of norms from.
246 * Retrieve a GList of available #GstTunerNorm settings for the currently
247 * tuned channel on the given tuner object.
249 * Returns: A list of norms available on the current channel for this
250 * tuner object. The list is owned by the GstTuner and must not
255 gst_tuner_list_norms (GstTuner * tuner)
257 GstTunerInterface *iface;
259 g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
261 iface = GST_TUNER_GET_INTERFACE (tuner);
262 if (iface->list_norms) {
263 return iface->list_norms (tuner);
270 * gst_tuner_set_norm:
271 * @tuner: the #GstTuner (a #GstElement) to set the norm on.
272 * @norm: the norm to use for the current channel.
274 * Changes the video norm on this tuner to the given norm, which should be
275 * one of the norms returned by gst_tuner_list_norms().
279 gst_tuner_set_norm (GstTuner * tuner, GstTunerNorm * norm)
281 GstTunerInterface *iface;
283 g_return_if_fail (GST_IS_TUNER (tuner));
285 iface = GST_TUNER_GET_INTERFACE (tuner);
286 if (iface->set_norm) {
287 iface->set_norm (tuner, norm);
292 * gst_tuner_get_norm:
293 * @tuner: the #GstTuner (a #GstElement) to get the current norm from.
295 * Get the current video norm from the given tuner object for the
296 * currently selected channel.
298 * Returns: the current norm.
302 gst_tuner_get_norm (GstTuner * tuner)
304 GstTunerInterface *iface;
306 g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
308 iface = GST_TUNER_GET_INTERFACE (tuner);
309 if (iface->get_norm) {
310 return iface->get_norm (tuner);
317 * gst_tuner_set_frequency:
318 * @tuner: The #GstTuner (a #GstElement) that owns the given channel.
319 * @channel: The #GstTunerChannel to set the frequency on.
320 * @frequency: The frequency to tune in to.
322 * Sets a tuning frequency on the given tuner/channel. Note that this
323 * requires the given channel to be a "tuning" channel, which can be
324 * checked using GST_TUNER_CHANNEL_HAS_FLAG (), with the proper flag
325 * being GST_TUNER_CHANNEL_FREQUENCY.
327 * The frequency is in Hz, with minimum steps indicated by the
328 * frequency_multiplicator provided in the #GstTunerChannel. The
329 * valid range is provided in the min_frequency and max_frequency properties
330 * of the #GstTunerChannel.
334 gst_tuner_set_frequency (GstTuner * tuner,
335 GstTunerChannel * channel, gulong frequency)
337 GstTunerInterface *iface;
339 g_return_if_fail (GST_IS_TUNER (tuner));
340 g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
341 g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
342 GST_TUNER_CHANNEL_FREQUENCY));
344 iface = GST_TUNER_GET_INTERFACE (tuner);
345 if (iface->set_frequency) {
346 iface->set_frequency (tuner, channel, frequency);
351 * gst_tuner_get_frequency:
352 * @tuner: The #GstTuner (a #GstElement) that owns the given channel.
353 * @channel: The #GstTunerChannel to retrieve the frequency from.
355 * Retrieve the current frequency from the given channel. As for
356 * gst_tuner_set_frequency(), the #GstTunerChannel must support frequency
357 * operations, as indicated by the GST_TUNER_CHANNEL_FREQUENCY flag.
359 * Returns: The current frequency, or 0 on error.
363 gst_tuner_get_frequency (GstTuner * tuner, GstTunerChannel * channel)
365 GstTunerInterface *iface;
367 g_return_val_if_fail (GST_IS_TUNER (tuner), 0);
368 g_return_val_if_fail (GST_IS_TUNER_CHANNEL (channel), 0);
369 g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
370 GST_TUNER_CHANNEL_FREQUENCY), 0);
372 iface = GST_TUNER_GET_INTERFACE (tuner);
374 if (iface->get_frequency) {
375 return iface->get_frequency (tuner, channel);
382 * gst_tuner_signal_strength:
383 * @tuner: the #GstTuner (a #GstElement) that owns the given channel.
384 * @channel: the #GstTunerChannel to get the signal strength from.
386 * Get the strength of the signal on this channel. Note that this
387 * requires the current channel to be a "tuning" channel, i.e. a
388 * channel on which frequency can be set. This can be checked using
389 * GST_TUNER_CHANNEL_HAS_FLAG (), and the appropriate flag to check
390 * for is GST_TUNER_CHANNEL_FREQUENCY.
392 * The valid range of the signal strength is indicated in the
393 * min_signal and max_signal properties of the #GstTunerChannel.
395 * Returns: Signal strength, or 0 on error.
398 gst_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel)
400 GstTunerInterface *iface;
402 g_return_val_if_fail (GST_IS_TUNER (tuner), 0);
403 g_return_val_if_fail (GST_IS_TUNER_CHANNEL (channel), 0);
404 g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
405 GST_TUNER_CHANNEL_FREQUENCY), 0);
407 iface = GST_TUNER_GET_INTERFACE (tuner);
408 if (iface->signal_strength) {
409 return iface->signal_strength (tuner, channel);
416 * gst_tuner_find_norm_by_name:
417 * @tuner: A #GstTuner instance
418 * @norm: A string containing the name of a #GstTunerNorm
420 * Look up a #GstTunerNorm by name.
422 * Returns: A #GstTunerNorm, or NULL if no norm with the provided name
426 gst_tuner_find_norm_by_name (GstTuner * tuner, gchar * norm)
430 g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
431 g_return_val_if_fail (norm != NULL, NULL);
433 walk = (GList *) gst_tuner_list_norms (tuner);
435 if (strcmp (GST_TUNER_NORM (walk->data)->label, norm) == 0)
436 return GST_TUNER_NORM (walk->data);
437 walk = g_list_next (walk);
443 * gst_tuner_find_channel_by_name:
444 * @tuner: A #GstTuner instance
445 * @channel: A string containing the name of a #GstTunerChannel
447 * Look up a #GstTunerChannel by name.
449 * Returns: A #GstTunerChannel, or NULL if no channel with the provided name
453 gst_tuner_find_channel_by_name (GstTuner * tuner, gchar * channel)
457 g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
458 g_return_val_if_fail (channel != NULL, NULL);
460 walk = (GList *) gst_tuner_list_channels (tuner);
462 if (strcmp (GST_TUNER_CHANNEL (walk->data)->label, channel) == 0)
463 return GST_TUNER_CHANNEL (walk->data);
464 walk = g_list_next (walk);
470 * gst_tuner_channel_changed:
471 * @tuner: A #GstTuner instance
472 * @channel: A #GstTunerChannel instance
474 * Called by elements implementing the #GstTuner interface when the
475 * current channel changes. Fires the #GstTuner::channel-changed signal.
478 gst_tuner_channel_changed (GstTuner * tuner, GstTunerChannel * channel)
480 g_return_if_fail (GST_IS_TUNER (tuner));
481 g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
483 g_signal_emit (G_OBJECT (tuner),
484 gst_tuner_signals[CHANNEL_CHANGED], 0, channel);
488 * gst_tuner_norm_changed:
489 * @tuner: A #GstTuner instance
490 * @norm: A #GstTunerNorm instance
492 * Called by elements implementing the #GstTuner interface when the
493 * current norm changes. Fires the #GstTuner::norm-changed signal.
497 gst_tuner_norm_changed (GstTuner * tuner, GstTunerNorm * norm)
499 g_return_if_fail (GST_IS_TUNER (tuner));
500 g_return_if_fail (GST_IS_TUNER_NORM (norm));
502 g_signal_emit (G_OBJECT (tuner), gst_tuner_signals[NORM_CHANGED], 0, norm);
506 * gst_tuner_frequency_changed:
507 * @tuner: A #GstTuner instance
508 * @channel: The current #GstTunerChannel
509 * @frequency: The new frequency setting
511 * Called by elements implementing the #GstTuner interface when the
512 * configured frequency changes. Fires the #GstTuner::frequency-changed
513 * signal on the tuner, and the #GstTunerChannel::frequency-changed signal
517 gst_tuner_frequency_changed (GstTuner * tuner,
518 GstTunerChannel * channel, gulong frequency)
520 g_return_if_fail (GST_IS_TUNER (tuner));
521 g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
523 g_signal_emit (G_OBJECT (tuner),
524 gst_tuner_signals[FREQUENCY_CHANGED], 0, channel, frequency);
526 g_signal_emit_by_name (G_OBJECT (channel), "frequency_changed", frequency);
530 * gst_tuner_signal_changed:
531 * @tuner: A #GstTuner instance
532 * @channel: The current #GstTunerChannel
533 * @signal: The new signal strength
535 * Called by elements implementing the #GstTuner interface when the
536 * incoming signal strength changes. Fires the #GstTuner::signal-changed
537 * signal on the tuner and the #GstTunerChannel::signal-changed signal on
541 gst_tuner_signal_changed (GstTuner * tuner,
542 GstTunerChannel * channel, gint signal)
544 g_return_if_fail (GST_IS_TUNER (tuner));
545 g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
547 g_signal_emit (G_OBJECT (tuner),
548 gst_tuner_signals[SIGNAL_CHANGED], 0, channel, signal);
550 g_signal_emit_by_name (G_OBJECT (channel), "signal_changed", signal);