mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-06 02:32:23 +00:00
Some changes proposed by wingo in bug #338818 (but not everything yet). Patch from Martin Rubli to fix framerate dete...
Original commit message from CVS: Some changes proposed by wingo in bug #338818 (but not everything yet). Patch from Martin Rubli to fix framerate detection.
This commit is contained in:
parent
e874927200
commit
ab273cf986
12 changed files with 294 additions and 184 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
2006-05-05 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
|
|
||||||
|
* sys/v4l2/gstv4l2element.c:
|
||||||
|
* sys/v4l2/gstv4l2element.h:
|
||||||
|
* sys/v4l2/gstv4l2src.c:
|
||||||
|
* sys/v4l2/gstv4l2src.h:
|
||||||
|
* sys/v4l2/gstv4l2tuner.c:
|
||||||
|
* sys/v4l2/gstv4l2tuner.h:
|
||||||
|
* sys/v4l2/v4l2_calls.c:
|
||||||
|
* sys/v4l2/v4l2_calls.h:
|
||||||
|
* sys/v4l2/v4l2src_calls.c:
|
||||||
|
* sys/v4l2/v4l2src_calls.h:
|
||||||
|
* tests/icles/v4l2src-test.c:
|
||||||
|
Some changes proposed by wingo in bug #338818 (but not everything
|
||||||
|
yet). Patch from Martin Rubli to fix framerate detection.
|
||||||
|
|
||||||
2006-05-05 Tim-Philipp Müller <tim at centricular dot net>
|
2006-05-05 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* ext/sdl/sdlaudiosink.c: (gst_sdlaudio_sink_prepare):
|
* ext/sdl/sdlaudiosink.c: (gst_sdlaudio_sink_prepare):
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* GStreamer gstv4l2element.c: base class for V4L2 elements Copyright
|
* GStreamer gstv4l2element.c: base class for V4L2 elements
|
||||||
* (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net> This library
|
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
* is free software; you can redistribute it and/or modify it under the
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
* terms of the GNU Library General Public License as published by the
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
* it under the terms of the GNU Library General Public License as published
|
||||||
* option) any later version. This library is distributed in the hope
|
* by the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version. This library is distributed in the hope
|
||||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
||||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
* PURPOSE. See the GNU Library General Public License for more details.
|
* PURPOSE. See the GNU Library General Public License for more details.
|
||||||
|
@ -49,19 +50,19 @@ enum
|
||||||
static void gst_v4l2element_init_interfaces (GType type);
|
static void gst_v4l2element_init_interfaces (GType type);
|
||||||
|
|
||||||
GST_BOILERPLATE_FULL (GstV4l2Element, gst_v4l2element, GstPushSrc,
|
GST_BOILERPLATE_FULL (GstV4l2Element, gst_v4l2element, GstPushSrc,
|
||||||
GST_TYPE_PUSH_SRC, gst_v4l2element_init_interfaces)
|
GST_TYPE_PUSH_SRC, gst_v4l2element_init_interfaces);
|
||||||
static void gst_v4l2element_dispose (GObject * object);
|
|
||||||
static void gst_v4l2element_set_property (GObject * object,
|
static void gst_v4l2element_dispose (GObject * object);
|
||||||
|
static void gst_v4l2element_set_property (GObject * object,
|
||||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||||
static void gst_v4l2element_get_property (GObject * object,
|
static void gst_v4l2element_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
static gboolean gst_v4l2element_start (GstBaseSrc * src);
|
static gboolean gst_v4l2element_start (GstBaseSrc * src);
|
||||||
static gboolean gst_v4l2element_stop (GstBaseSrc * src);
|
static gboolean gst_v4l2element_stop (GstBaseSrc * src);
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2_iface_supported (GstImplementsInterface * iface,
|
gst_v4l2_iface_supported (GstImplementsInterface * iface, GType iface_type)
|
||||||
GType iface_type)
|
|
||||||
{
|
{
|
||||||
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (iface);
|
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (iface);
|
||||||
|
|
||||||
|
@ -99,10 +100,16 @@ gst_v4l2_probe_get_properties (GstPropertyProbe * probe)
|
||||||
GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
|
GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
|
||||||
static GList *list = NULL;
|
static GList *list = NULL;
|
||||||
|
|
||||||
|
/* well, not perfect, but better than no locking at all.
|
||||||
|
* In the worst case we leak a list node, so who cares? */
|
||||||
|
GST_CLASS_LOCK (GST_OBJECT_CLASS (klass));
|
||||||
|
|
||||||
if (!list) {
|
if (!list) {
|
||||||
list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
|
list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,12 +442,13 @@ gst_v4l2element_set_property (GObject * object,
|
||||||
g_value_get_string (value));
|
g_value_get_string (value));
|
||||||
|
|
||||||
if (norm) {
|
if (norm) {
|
||||||
gst_tuner_set_norm (tuner, norm);
|
/* more generic would be gst_tuner_set_norm (tuner, norm)
|
||||||
|
without g_object_notify */
|
||||||
|
gst_v4l2_tuner_set_norm (tuner, norm);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g_free (v4l2element->std);
|
g_free (v4l2element->std);
|
||||||
v4l2element->std = g_value_dup_string (value);
|
v4l2element->std = g_value_dup_string (value);
|
||||||
g_object_notify (object, "std");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_INPUT:
|
case PROP_INPUT:
|
||||||
|
@ -451,12 +459,13 @@ gst_v4l2element_set_property (GObject * object,
|
||||||
g_value_get_string (value));
|
g_value_get_string (value));
|
||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
gst_tuner_set_channel (tuner, channel);
|
/* more generic would be gst_tuner_set_channel (tuner, channel)
|
||||||
|
without g_object_notify */
|
||||||
|
gst_v4l2_tuner_set_channel (tuner, channel);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g_free (v4l2element->input);
|
g_free (v4l2element->input);
|
||||||
v4l2element->input = g_value_dup_string (value);
|
v4l2element->input = g_value_dup_string (value);
|
||||||
g_object_notify (object, "input");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_FREQUENCY:
|
case PROP_FREQUENCY:
|
||||||
|
@ -466,11 +475,14 @@ gst_v4l2element_set_property (GObject * object,
|
||||||
|
|
||||||
if (channel &&
|
if (channel &&
|
||||||
GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
|
GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
|
||||||
gst_tuner_set_frequency (tuner, channel, g_value_get_ulong (value));
|
/* more generic would be
|
||||||
|
gst_tuner_set_frequency (tuner, channel, g_value_get_ulong (value))
|
||||||
|
without g_object_notify */
|
||||||
|
gst_v4l2_tuner_set_frequency (tuner, channel,
|
||||||
|
g_value_get_ulong (value));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
v4l2element->frequency = g_value_get_ulong (value);
|
v4l2element->frequency = g_value_get_ulong (value);
|
||||||
g_object_notify (object, "frequency");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* gstv4l2element.h: base class for V4L2 elements
|
* gstv4l2element.h: base class for V4L2 elements
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* gstv4l2src.c: BT8x8/V4L2 source element
|
* gstv4l2src.c: BT8x8/V4L2 source element
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -207,6 +208,8 @@ gst_v4l2src_init (GstV4l2Src * v4l2src, GstV4l2SrcClass * klass)
|
||||||
v4l2src->formats = NULL;
|
v4l2src->formats = NULL;
|
||||||
|
|
||||||
/* fps */
|
/* fps */
|
||||||
|
v4l2src->fps_n = 0;
|
||||||
|
v4l2src->fps_d = 1;
|
||||||
v4l2src->use_fixed_fps = TRUE;
|
v4l2src->use_fixed_fps = TRUE;
|
||||||
|
|
||||||
v4l2src->is_capturing = FALSE;
|
v4l2src->is_capturing = FALSE;
|
||||||
|
@ -631,8 +634,7 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
|
||||||
int min_w, max_w, min_h, max_h;
|
int min_w, max_w, min_h, max_h;
|
||||||
GSList *walk;
|
GSList *walk;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
gint fps_n, fps_d;
|
guint fps_n, fps_d;
|
||||||
|
|
||||||
|
|
||||||
if (!GST_V4L2_IS_OPEN (GST_V4L2ELEMENT (v4l2src))) {
|
if (!GST_V4L2_IS_OPEN (GST_V4L2ELEMENT (v4l2src))) {
|
||||||
return
|
return
|
||||||
|
@ -647,6 +649,7 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
|
||||||
caps = gst_caps_new_empty ();
|
caps = gst_caps_new_empty ();
|
||||||
walk = v4l2src->formats;
|
walk = v4l2src->formats;
|
||||||
if (!gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d)) {
|
if (!gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d)) {
|
||||||
|
GST_DEBUG_OBJECT (v4l2src, "frame rate is unknown.");
|
||||||
fps_n = 0;
|
fps_n = 0;
|
||||||
fps_d = 1;
|
fps_d = 1;
|
||||||
}
|
}
|
||||||
|
@ -857,10 +860,8 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
|
||||||
{
|
{
|
||||||
GstV4l2Src *v4l2src = GST_V4L2SRC (src);
|
GstV4l2Src *v4l2src = GST_V4L2SRC (src);
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint fps_n, fps_d;
|
|
||||||
|
|
||||||
if (v4l2src->use_fixed_fps
|
if (v4l2src->use_fixed_fps && v4l2src->fps_n == 0) {
|
||||||
&& gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d) == 0) {
|
|
||||||
GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
|
GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
|
||||||
("could not get frame rate for element"));
|
("could not get frame rate for element"));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* gstv4l2src.h: BT8x8/V4L2 video source element
|
* gstv4l2src.h: BT8x8/V4L2 video source element
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -97,6 +98,7 @@ struct _GstV4l2Src
|
||||||
gint offset;
|
gint offset;
|
||||||
|
|
||||||
/* how are we going to push buffers? */
|
/* how are we going to push buffers? */
|
||||||
|
guint fps_n, fps_d;
|
||||||
gboolean use_fixed_fps;
|
gboolean use_fixed_fps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* GStreamer Tuner interface implementation
|
/* GStreamer Tuner interface implementation
|
||||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* gstv4l2tuner.c: tuner interface implementation for V4L2
|
* gstv4l2tuner.c: tuner interface implementation for V4L2
|
||||||
*
|
*
|
||||||
|
@ -28,6 +29,9 @@
|
||||||
#include "gstv4l2tuner.h"
|
#include "gstv4l2tuner.h"
|
||||||
#include "gstv4l2element.h"
|
#include "gstv4l2element.h"
|
||||||
#include "v4l2_calls.h"
|
#include "v4l2_calls.h"
|
||||||
|
#include "v4l2src_calls.h"
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
static void gst_v4l2_tuner_channel_class_init (GstV4l2TunerChannelClass *
|
static void gst_v4l2_tuner_channel_class_init (GstV4l2TunerChannelClass *
|
||||||
klass);
|
klass);
|
||||||
|
@ -37,21 +41,35 @@ static void gst_v4l2_tuner_norm_class_init (GstV4l2TunerNormClass * klass);
|
||||||
static void gst_v4l2_tuner_norm_init (GstV4l2TunerNorm * norm);
|
static void gst_v4l2_tuner_norm_init (GstV4l2TunerNorm * norm);
|
||||||
|
|
||||||
static const GList *gst_v4l2_tuner_list_channels (GstTuner * mixer);
|
static const GList *gst_v4l2_tuner_list_channels (GstTuner * mixer);
|
||||||
static void gst_v4l2_tuner_set_channel (GstTuner * mixer,
|
|
||||||
|
static void
|
||||||
|
gst_v4l2_tuner_set_channel_and_notify (GstTuner * mixer,
|
||||||
GstTunerChannel * channel);
|
GstTunerChannel * channel);
|
||||||
static GstTunerChannel *gst_v4l2_tuner_get_channel (GstTuner * mixer);
|
static GstTunerChannel *gst_v4l2_tuner_get_channel (GstTuner * mixer);
|
||||||
|
|
||||||
static const GList *gst_v4l2_tuner_list_norms (GstTuner * mixer);
|
static const GList *gst_v4l2_tuner_list_norms (GstTuner * mixer);
|
||||||
static void gst_v4l2_tuner_set_norm (GstTuner * mixer, GstTunerNorm * norm);
|
|
||||||
|
static void
|
||||||
|
gst_v4l2_tuner_set_norm_and_notify (GstTuner * mixer, GstTunerNorm * norm);
|
||||||
static GstTunerNorm *gst_v4l2_tuner_get_norm (GstTuner * mixer);
|
static GstTunerNorm *gst_v4l2_tuner_get_norm (GstTuner * mixer);
|
||||||
|
|
||||||
static void gst_v4l2_tuner_set_frequency (GstTuner * mixer,
|
static void
|
||||||
|
gst_v4l2_tuner_set_frequency_and_notify (GstTuner * mixer,
|
||||||
GstTunerChannel * channel, gulong frequency);
|
GstTunerChannel * channel, gulong frequency);
|
||||||
static gulong gst_v4l2_tuner_get_frequency (GstTuner * mixer,
|
static gulong gst_v4l2_tuner_get_frequency (GstTuner * mixer,
|
||||||
GstTunerChannel * channel);
|
GstTunerChannel * channel);
|
||||||
static gint gst_v4l2_tuner_signal_strength (GstTuner * mixer,
|
static gint gst_v4l2_tuner_signal_strength (GstTuner * mixer,
|
||||||
GstTunerChannel * channel);
|
GstTunerChannel * channel);
|
||||||
|
|
||||||
|
static gboolean gst_v4l2_get_input (GstV4l2Element * v4l2element, gint * input);
|
||||||
|
static gboolean gst_v4l2_set_input (GstV4l2Element * v4l2element, gint input);
|
||||||
|
|
||||||
|
#if 0 /* output not handled by now */
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2_get_output (GstV4l2Element * v4l2element, gint * output);
|
||||||
|
static gboolean gst_v4l2_set_output (GstV4l2Element * v4l2element, gint output);
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
|
|
||||||
static GstTunerNormClass *norm_parent_class = NULL;
|
static GstTunerNormClass *norm_parent_class = NULL;
|
||||||
static GstTunerChannelClass *channel_parent_class = NULL;
|
static GstTunerChannelClass *channel_parent_class = NULL;
|
||||||
|
|
||||||
|
@ -140,18 +158,19 @@ gst_v4l2_tuner_interface_init (GstTunerClass * klass)
|
||||||
{
|
{
|
||||||
/* default virtual functions */
|
/* default virtual functions */
|
||||||
klass->list_channels = gst_v4l2_tuner_list_channels;
|
klass->list_channels = gst_v4l2_tuner_list_channels;
|
||||||
klass->set_channel = gst_v4l2_tuner_set_channel;
|
klass->set_channel = gst_v4l2_tuner_set_channel_and_notify;
|
||||||
klass->get_channel = gst_v4l2_tuner_get_channel;
|
klass->get_channel = gst_v4l2_tuner_get_channel;
|
||||||
|
|
||||||
klass->list_norms = gst_v4l2_tuner_list_norms;
|
klass->list_norms = gst_v4l2_tuner_list_norms;
|
||||||
klass->set_norm = gst_v4l2_tuner_set_norm;
|
klass->set_norm = gst_v4l2_tuner_set_norm_and_notify;
|
||||||
klass->get_norm = gst_v4l2_tuner_get_norm;
|
klass->get_norm = gst_v4l2_tuner_get_norm;
|
||||||
|
|
||||||
klass->set_frequency = gst_v4l2_tuner_set_frequency;
|
klass->set_frequency = gst_v4l2_tuner_set_frequency_and_notify;
|
||||||
klass->get_frequency = gst_v4l2_tuner_get_frequency;
|
klass->get_frequency = gst_v4l2_tuner_get_frequency;
|
||||||
klass->signal_strength = gst_v4l2_tuner_signal_strength;
|
klass->signal_strength = gst_v4l2_tuner_signal_strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* output not handled by now */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2_tuner_is_sink (GstV4l2Element * v4l2element)
|
gst_v4l2_tuner_is_sink (GstV4l2Element * v4l2element)
|
||||||
{
|
{
|
||||||
|
@ -159,6 +178,7 @@ gst_v4l2_tuner_is_sink (GstV4l2Element * v4l2element)
|
||||||
|
|
||||||
return (dir == GST_PAD_SINK);
|
return (dir == GST_PAD_SINK);
|
||||||
}
|
}
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
|
|
||||||
static G_GNUC_UNUSED gboolean
|
static G_GNUC_UNUSED gboolean
|
||||||
gst_v4l2_tuner_contains_channel (GstV4l2Element * v4l2element,
|
gst_v4l2_tuner_contains_channel (GstV4l2Element * v4l2element,
|
||||||
|
@ -176,29 +196,86 @@ gst_v4l2_tuner_contains_channel (GstV4l2Element * v4l2element,
|
||||||
static const GList *
|
static const GList *
|
||||||
gst_v4l2_tuner_list_channels (GstTuner * mixer)
|
gst_v4l2_tuner_list_channels (GstTuner * mixer)
|
||||||
{
|
{
|
||||||
/* ... or output, if we're a sink... */
|
|
||||||
return GST_V4L2ELEMENT (mixer)->inputs;
|
return GST_V4L2ELEMENT (mixer)->inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_v4l2_tuner_set_channel (GstTuner * mixer, GstTunerChannel * channel)
|
gst_v4l2_tuner_set_channel_and_notify (GstTuner * mixer,
|
||||||
|
GstTunerChannel * channel)
|
||||||
{
|
{
|
||||||
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
|
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
|
||||||
GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel);
|
|
||||||
|
|
||||||
/* assert that we're opened and that we're using a known item */
|
if (gst_v4l2_tuner_set_channel (mixer, channel)) {
|
||||||
g_return_if_fail (GST_V4L2_IS_OPEN (v4l2element));
|
|
||||||
g_return_if_fail (gst_v4l2_tuner_contains_channel (v4l2element, v4l2channel));
|
|
||||||
|
|
||||||
/* ... or output, if we're a sink... */
|
|
||||||
if (gst_v4l2_tuner_is_sink (v4l2element) ?
|
|
||||||
gst_v4l2_set_output (v4l2element, v4l2channel->index) :
|
|
||||||
gst_v4l2_set_input (v4l2element, v4l2channel->index)) {
|
|
||||||
gst_tuner_channel_changed (mixer, channel);
|
|
||||||
g_object_notify (G_OBJECT (v4l2element), "input");
|
g_object_notify (G_OBJECT (v4l2element), "input");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_tuner_set_channel (GstTuner * mixer, GstTunerChannel * channel)
|
||||||
|
{
|
||||||
|
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
|
||||||
|
GstV4l2Src *v4l2src = GST_V4L2SRC (v4l2element);
|
||||||
|
GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel);
|
||||||
|
|
||||||
|
/* assert that we're opened and that we're using a known item */
|
||||||
|
g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), FALSE);
|
||||||
|
g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2element,
|
||||||
|
v4l2channel), FALSE);
|
||||||
|
|
||||||
|
if (
|
||||||
|
#if 0 /* output not handled by now */
|
||||||
|
gst_v4l2_tuner_is_sink (v4l2element) ?
|
||||||
|
gst_v4l2_set_output (v4l2element, v4l2channel->index) :
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
|
gst_v4l2_set_input (v4l2element, v4l2channel->index)
|
||||||
|
) {
|
||||||
|
gst_tuner_channel_changed (mixer, channel);
|
||||||
|
gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2_get_input (GstV4l2Element * v4l2element, gint * input)
|
||||||
|
{
|
||||||
|
gint n;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (v4l2element, "trying to get input");
|
||||||
|
if (!GST_V4L2_IS_OPEN (v4l2element))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (ioctl (v4l2element->video_fd, VIDIOC_G_INPUT, &n) < 0) {
|
||||||
|
GST_WARNING_OBJECT (v4l2element,
|
||||||
|
"Failed to get current input on device %s: %s",
|
||||||
|
v4l2element->videodev, g_strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*input = n;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2_set_input (GstV4l2Element * v4l2element, gint input)
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (v4l2element, "trying to set input to %d", input);
|
||||||
|
if (!GST_V4L2_IS_OPEN (v4l2element))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (ioctl (v4l2element->video_fd, VIDIOC_S_INPUT, &input) < 0) {
|
||||||
|
GST_WARNING_OBJECT (v4l2element, "Failed to set input %d on device %s: %s",
|
||||||
|
input, v4l2element->videodev, g_strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static GstTunerChannel *
|
static GstTunerChannel *
|
||||||
gst_v4l2_tuner_get_channel (GstTuner * mixer)
|
gst_v4l2_tuner_get_channel (GstTuner * mixer)
|
||||||
{
|
{
|
||||||
|
@ -209,10 +286,11 @@ gst_v4l2_tuner_get_channel (GstTuner * mixer)
|
||||||
/* assert that we're opened and that we're using a known item */
|
/* assert that we're opened and that we're using a known item */
|
||||||
g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), NULL);
|
g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), NULL);
|
||||||
|
|
||||||
/* ... or output, if we're a sink... */
|
#if 0 /* output not handled by now */
|
||||||
if (gst_v4l2_tuner_is_sink (v4l2element))
|
if (gst_v4l2_tuner_is_sink (v4l2element))
|
||||||
gst_v4l2_get_output (v4l2element, &channel);
|
gst_v4l2_get_output (v4l2element, &channel);
|
||||||
else
|
else
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
gst_v4l2_get_input (v4l2element, &channel);
|
gst_v4l2_get_input (v4l2element, &channel);
|
||||||
|
|
||||||
for (item = v4l2element->inputs; item != NULL; item = item->next) {
|
for (item = v4l2element->inputs; item != NULL; item = item->next) {
|
||||||
|
@ -243,19 +321,35 @@ gst_v4l2_tuner_list_norms (GstTuner * mixer)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
gst_v4l2_tuner_set_norm_and_notify (GstTuner * mixer, GstTunerNorm * norm)
|
||||||
|
{
|
||||||
|
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
|
||||||
|
|
||||||
|
if (gst_v4l2_tuner_set_norm (mixer, norm)) {
|
||||||
|
g_object_notify (G_OBJECT (v4l2element), "std");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
gst_v4l2_tuner_set_norm (GstTuner * mixer, GstTunerNorm * norm)
|
gst_v4l2_tuner_set_norm (GstTuner * mixer, GstTunerNorm * norm)
|
||||||
{
|
{
|
||||||
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
|
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
|
||||||
|
GstV4l2Src *v4l2src = GST_V4L2SRC (v4l2element);
|
||||||
GstV4l2TunerNorm *v4l2norm = GST_V4L2_TUNER_NORM (norm);
|
GstV4l2TunerNorm *v4l2norm = GST_V4L2_TUNER_NORM (norm);
|
||||||
|
|
||||||
/* assert that we're opened and that we're using a known item */
|
/* assert that we're opened and that we're using a known item */
|
||||||
g_return_if_fail (GST_V4L2_IS_OPEN (v4l2element));
|
g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), FALSE);
|
||||||
g_return_if_fail (gst_v4l2_tuner_contains_norm (v4l2element, v4l2norm));
|
g_return_val_if_fail (gst_v4l2_tuner_contains_norm (v4l2element, v4l2norm),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
if (gst_v4l2_set_norm (v4l2element, v4l2norm->index)) {
|
if (gst_v4l2_set_norm (v4l2element, v4l2norm->index)) {
|
||||||
gst_tuner_norm_changed (mixer, norm);
|
gst_tuner_norm_changed (mixer, norm);
|
||||||
g_object_notify (G_OBJECT (v4l2element), "std");
|
gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstTunerNorm *
|
static GstTunerNorm *
|
||||||
|
@ -279,6 +373,17 @@ gst_v4l2_tuner_get_norm (GstTuner * mixer)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
gst_v4l2_tuner_set_frequency_and_notify (GstTuner * mixer,
|
||||||
|
GstTunerChannel * channel, gulong frequency)
|
||||||
|
{
|
||||||
|
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
|
||||||
|
|
||||||
|
if (gst_v4l2_tuner_set_frequency (mixer, channel, frequency)) {
|
||||||
|
g_object_notify (G_OBJECT (v4l2element), "frequency");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
gst_v4l2_tuner_set_frequency (GstTuner * mixer,
|
gst_v4l2_tuner_set_frequency (GstTuner * mixer,
|
||||||
GstTunerChannel * channel, gulong frequency)
|
GstTunerChannel * channel, gulong frequency)
|
||||||
{
|
{
|
||||||
|
@ -287,19 +392,21 @@ gst_v4l2_tuner_set_frequency (GstTuner * mixer,
|
||||||
gint chan;
|
gint chan;
|
||||||
|
|
||||||
/* assert that we're opened and that we're using a known item */
|
/* assert that we're opened and that we're using a known item */
|
||||||
g_return_if_fail (GST_V4L2_IS_OPEN (v4l2element));
|
g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), FALSE);
|
||||||
g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
|
g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
|
||||||
GST_TUNER_CHANNEL_FREQUENCY));
|
GST_TUNER_CHANNEL_FREQUENCY), FALSE);
|
||||||
g_return_if_fail (gst_v4l2_tuner_contains_channel (v4l2element, v4l2channel));
|
g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2element,
|
||||||
|
v4l2channel), FALSE);
|
||||||
|
|
||||||
gst_v4l2_get_input (v4l2element, &chan);
|
gst_v4l2_get_input (v4l2element, &chan);
|
||||||
if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index &&
|
if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index &&
|
||||||
GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
|
GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
|
||||||
if (gst_v4l2_set_frequency (v4l2element, v4l2channel->tuner, frequency)) {
|
if (gst_v4l2_set_frequency (v4l2element, v4l2channel->tuner, frequency)) {
|
||||||
gst_tuner_frequency_changed (mixer, channel, frequency);
|
gst_tuner_frequency_changed (mixer, channel, frequency);
|
||||||
g_object_notify (G_OBJECT (v4l2element), "frequency");
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gulong
|
static gulong
|
||||||
|
@ -349,3 +456,47 @@ gst_v4l2_tuner_signal_strength (GstTuner * mixer, GstTunerChannel * channel)
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* output not handled by now */
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2_get_output (GstV4l2Element * v4l2element, gint * output)
|
||||||
|
{
|
||||||
|
gint n;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (v4l2element, "trying to get output");
|
||||||
|
if (!GST_V4L2_IS_OPEN (v4l2element))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (ioctl (v4l2element->video_fd, VIDIOC_G_OUTPUT, &n) < 0) {
|
||||||
|
GST_WARNING_OBJECT (v4l2element,
|
||||||
|
"Failed to get current output on device %s: %s",
|
||||||
|
v4l2element->videodev, g_strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output = n;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2_set_output (GstV4l2Element * v4l2element, gint output)
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (v4l2element, "trying to set output to %d", output);
|
||||||
|
if (!GST_V4L2_IS_OPEN (v4l2element))
|
||||||
|
return FALSE;
|
||||||
|
if (!GST_V4L2_IS_ACTIVE (v4l2element))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (ioctl (v4l2element->video_fd, VIDIOC_S_OUTPUT, &output) < 0) {
|
||||||
|
GST_WARNING_OBJECT (v4l2element,
|
||||||
|
"Failed to set current output on device %s to %d: %s",
|
||||||
|
v4l2element->videodev, output, g_strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* G-Streamer generic V4L2 element - Tuner interface implementation
|
/* G-Streamer generic V4L2 element - Tuner interface implementation
|
||||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* gstv4l2tuner.h: tuner interface implementation for V4L2
|
* gstv4l2tuner.h: tuner interface implementation for V4L2
|
||||||
*
|
*
|
||||||
|
@ -82,4 +83,14 @@ GType gst_v4l2_tuner_norm_get_type (void);
|
||||||
|
|
||||||
void gst_v4l2_tuner_interface_init (GstTunerClass *klass);
|
void gst_v4l2_tuner_interface_init (GstTunerClass *klass);
|
||||||
|
|
||||||
|
extern gboolean
|
||||||
|
gst_v4l2_tuner_set_channel (GstTuner * mixer, GstTunerChannel * channel);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_tuner_set_norm (GstTuner * mixer, GstTunerNorm * norm);
|
||||||
|
|
||||||
|
extern gboolean
|
||||||
|
gst_v4l2_tuner_set_frequency (GstTuner * mixer,
|
||||||
|
GstTunerChannel * channel, gulong frequency);
|
||||||
|
|
||||||
#endif /* __GST_V4L2_TUNER_H__ */
|
#endif /* __GST_V4L2_TUNER_H__ */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* G-Streamer generic V4L2 element - generic V4L2 calls handling
|
/* G-Streamer generic V4L2 element - generic V4L2 calls handling
|
||||||
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -73,12 +74,18 @@ static gboolean
|
||||||
gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
|
gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
|
||||||
{
|
{
|
||||||
gint n;
|
gint n;
|
||||||
|
|
||||||
|
#if 0 /* output not handled by now */
|
||||||
GstPadDirection dir = GST_PAD_UNKNOWN;
|
GstPadDirection dir = GST_PAD_UNKNOWN;
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2element, "getting enumerations");
|
GST_DEBUG_OBJECT (v4l2element, "getting enumerations");
|
||||||
GST_V4L2_CHECK_OPEN (v4l2element);
|
GST_V4L2_CHECK_OPEN (v4l2element);
|
||||||
|
|
||||||
|
#if 0 /* output not handled by now */
|
||||||
if (dir != GST_PAD_SINK) {
|
if (dir != GST_PAD_SINK) {
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
|
|
||||||
/* and now, the inputs */
|
/* and now, the inputs */
|
||||||
for (n = 0;; n++) {
|
for (n = 0;; n++) {
|
||||||
struct v4l2_input input;
|
struct v4l2_input input;
|
||||||
|
@ -134,6 +141,8 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
|
||||||
v4l2element->inputs =
|
v4l2element->inputs =
|
||||||
g_list_append (v4l2element->inputs, (gpointer) channel);
|
g_list_append (v4l2element->inputs, (gpointer) channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* output not handled by now */
|
||||||
} else {
|
} else {
|
||||||
/* outputs */
|
/* outputs */
|
||||||
for (n = 0;; n++) {
|
for (n = 0;; n++) {
|
||||||
|
@ -170,6 +179,7 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
|
||||||
g_list_append (v4l2element->inputs, (gpointer) channel);
|
g_list_append (v4l2element->inputs, (gpointer) channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* #if 0 - output not handled by now */
|
||||||
|
|
||||||
/* norms... */
|
/* norms... */
|
||||||
for (n = 0;; n++) {
|
for (n = 0;; n++) {
|
||||||
|
@ -501,6 +511,8 @@ gst_v4l2_get_norm (GstV4l2Element * v4l2element, v4l2_std_id * norm)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,8 +529,6 @@ gst_v4l2_set_norm (GstV4l2Element * v4l2element, v4l2_std_id norm)
|
||||||
GST_DEBUG_OBJECT (v4l2element, "trying to set norm to %llx", norm);
|
GST_DEBUG_OBJECT (v4l2element, "trying to set norm to %llx", norm);
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2element))
|
if (!GST_V4L2_IS_OPEN (v4l2element))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!GST_V4L2_IS_ACTIVE (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (ioctl (v4l2element->video_fd, VIDIOC_S_STD, &norm) < 0) {
|
if (ioctl (v4l2element->video_fd, VIDIOC_S_STD, &norm) < 0) {
|
||||||
GST_WARNING_OBJECT (v4l2element,
|
GST_WARNING_OBJECT (v4l2element,
|
||||||
|
@ -530,114 +540,6 @@ gst_v4l2_set_norm (GstV4l2Element * v4l2element, v4l2_std_id norm)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2_get_input()
|
|
||||||
* Get the input of the current device
|
|
||||||
* return value: TRUE on success, FALSE on error
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
gst_v4l2_get_input (GstV4l2Element * v4l2element, gint * input)
|
|
||||||
{
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2element, "trying to get input");
|
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (ioctl (v4l2element->video_fd, VIDIOC_G_INPUT, &n) < 0) {
|
|
||||||
GST_WARNING_OBJECT (v4l2element,
|
|
||||||
"Failed to get current input on device %s: %s",
|
|
||||||
v4l2element->videodev, g_strerror (errno));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*input = n;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2_set_input()
|
|
||||||
* Set the input of the current device
|
|
||||||
* return value: TRUE on success, FALSE on error
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
gst_v4l2_set_input (GstV4l2Element * v4l2element, gint input)
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (v4l2element, "trying to set input to %d", input);
|
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
if (!GST_V4L2_IS_ACTIVE (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (ioctl (v4l2element->video_fd, VIDIOC_S_INPUT, &input) < 0) {
|
|
||||||
GST_WARNING_OBJECT (v4l2element, "Failed to set input %d on device %s: %s",
|
|
||||||
input, v4l2element->videodev, g_strerror (errno));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2_get_output()
|
|
||||||
* Get the output of the current device
|
|
||||||
* return value: TRUE on success, FALSE on error
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
gst_v4l2_get_output (GstV4l2Element * v4l2element, gint * output)
|
|
||||||
{
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2element, "trying to get output");
|
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (ioctl (v4l2element->video_fd, VIDIOC_G_OUTPUT, &n) < 0) {
|
|
||||||
GST_WARNING_OBJECT (v4l2element,
|
|
||||||
"Failed to get current output on device %s: %s",
|
|
||||||
v4l2element->videodev, g_strerror (errno));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*output = n;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2_set_output()
|
|
||||||
* Set the output of the current device
|
|
||||||
* return value: TRUE on success, FALSE on error
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
gst_v4l2_set_output (GstV4l2Element * v4l2element, gint output)
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (v4l2element, "trying to set output to %d", output);
|
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
if (!GST_V4L2_IS_ACTIVE (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (ioctl (v4l2element->video_fd, VIDIOC_S_OUTPUT, &output) < 0) {
|
|
||||||
GST_WARNING_OBJECT (v4l2element,
|
|
||||||
"Failed to set current output on device %s to %d: %s",
|
|
||||||
v4l2element->videodev, output, g_strerror (errno));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l2_get_frequency():
|
* gst_v4l2_get_frequency():
|
||||||
* get the current frequency
|
* get the current frequency
|
||||||
|
@ -688,8 +590,6 @@ gst_v4l2_set_frequency (GstV4l2Element * v4l2element,
|
||||||
frequency);
|
frequency);
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2element))
|
if (!GST_V4L2_IS_OPEN (v4l2element))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!GST_V4L2_IS_ACTIVE (v4l2element))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
channel = gst_tuner_get_channel (GST_TUNER (v4l2element));
|
channel = gst_tuner_get_channel (GST_TUNER (v4l2element));
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* G-Streamer generic V4L2 element - generic V4L2 calls handling
|
/* G-Streamer generic V4L2 element - generic V4L2 calls handling
|
||||||
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -90,10 +91,6 @@ gboolean gst_v4l2_get_norm (GstV4l2Element *v4l2element,
|
||||||
v4l2_std_id *norm);
|
v4l2_std_id *norm);
|
||||||
gboolean gst_v4l2_set_norm (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_set_norm (GstV4l2Element *v4l2element,
|
||||||
v4l2_std_id norm);
|
v4l2_std_id norm);
|
||||||
gboolean gst_v4l2_get_input (GstV4l2Element *v4l2element,
|
|
||||||
gint *input);
|
|
||||||
gboolean gst_v4l2_set_input (GstV4l2Element *v4l2element,
|
|
||||||
gint input);
|
|
||||||
gboolean gst_v4l2_get_output (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_get_output (GstV4l2Element *v4l2element,
|
||||||
gint *output);
|
gint *output);
|
||||||
gboolean gst_v4l2_set_output (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_set_output (GstV4l2Element *v4l2element,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* G-Streamer Video4linux2 video-capture plugin - system calls
|
/* G-Streamer Video4linux2 video-capture plugin - system calls
|
||||||
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -319,6 +320,13 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine the device's framerate */
|
||||||
|
if (!gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d)) {
|
||||||
|
GST_DEBUG_OBJECT (v4l2src, "frame rate is unknown.");
|
||||||
|
v4l2src->fps_d = 1;
|
||||||
|
v4l2src->fps_n = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (v4l2src->breq.memory > 0) {
|
if (v4l2src->breq.memory > 0) {
|
||||||
if (v4l2src->breq.count < GST_V4L2_MIN_BUFFERS) {
|
if (v4l2src->breq.count < GST_V4L2_MIN_BUFFERS) {
|
||||||
GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
|
GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
|
||||||
|
@ -588,7 +596,7 @@ gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
|
||||||
fmt.fmt.pix.height);
|
fmt.fmt.pix.height);
|
||||||
|
|
||||||
fmt.fmt.pix.width = G_MAXINT;
|
fmt.fmt.pix.width = G_MAXINT;
|
||||||
fmt.fmt.pix.height = 576;
|
fmt.fmt.pix.height = G_MAXINT;
|
||||||
if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
|
if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -604,14 +612,28 @@ gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2src_get_fps (GstV4l2Src * v4l2src, gint * fps_n, gint * fps_d)
|
gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d)
|
||||||
{
|
{
|
||||||
v4l2_std_id std;
|
v4l2_std_id std;
|
||||||
|
struct v4l2_streamparm stream;
|
||||||
const GList *item;
|
const GList *item;
|
||||||
|
|
||||||
if (!GST_V4L2_IS_OPEN (GST_V4L2ELEMENT (v4l2src)))
|
if (!GST_V4L2_IS_OPEN (GST_V4L2ELEMENT (v4l2src)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* Try to get the frame rate directly from the device using VIDIOC_G_PARM */
|
||||||
|
stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_G_PARM, &stream) == 0
|
||||||
|
&& stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
|
||||||
|
/* Note: V4L2 gives us the frame interval, we need the frame rate */
|
||||||
|
*fps_n = stream.parm.capture.timeperframe.denominator;
|
||||||
|
*fps_d = stream.parm.capture.timeperframe.numerator;
|
||||||
|
GST_DEBUG_OBJECT (v4l2src, "frame rate returned by G_PARM: %d/%d fps",
|
||||||
|
*fps_n, *fps_d);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If G_PARM failed, try to get the same information from the video standard */
|
||||||
if (!gst_v4l2_get_norm (GST_V4L2ELEMENT (v4l2src), &std))
|
if (!gst_v4l2_get_norm (GST_V4L2ELEMENT (v4l2src), &std))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for (item = GST_V4L2ELEMENT (v4l2src)->stds; item != NULL; item = item->next) {
|
for (item = GST_V4L2ELEMENT (v4l2src)->stds; item != NULL; item = item->next) {
|
||||||
|
@ -624,6 +646,8 @@ gst_v4l2src_get_fps (GstV4l2Src * v4l2src, gint * fps_n, gint * fps_d)
|
||||||
*fps_d =
|
*fps_d =
|
||||||
gst_value_get_fraction_denominator (&GST_TUNER_NORM (v4l2norm)->
|
gst_value_get_fraction_denominator (&GST_TUNER_NORM (v4l2norm)->
|
||||||
framerate);
|
framerate);
|
||||||
|
GST_DEBUG_OBJECT (v4l2src, "frame rate returned by get_norm: %d/%d fps",
|
||||||
|
*fps_n, *fps_d);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,14 +804,8 @@ gst_v4l2src_buffer_new (GstV4l2Src * v4l2src, guint size, guint8 * data,
|
||||||
GstV4l2Buffer * srcbuf)
|
GstV4l2Buffer * srcbuf)
|
||||||
{
|
{
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
gint fps_n, fps_d;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2src, "creating buffer %d");
|
GST_LOG_OBJECT (v4l2src, "creating buffer %d");
|
||||||
|
|
||||||
if (!gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d)) {
|
|
||||||
fps_n = 0;
|
|
||||||
fps_d = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
buf = gst_buffer_new_and_alloc (size);
|
buf = gst_buffer_new_and_alloc (size);
|
||||||
|
@ -805,9 +823,9 @@ gst_v4l2src_buffer_new (GstV4l2Src * v4l2src, guint size, guint8 * data,
|
||||||
GST_BUFFER_TIMESTAMP (buf) -= GST_ELEMENT (v4l2src)->base_time;
|
GST_BUFFER_TIMESTAMP (buf) -= GST_ELEMENT (v4l2src)->base_time;
|
||||||
|
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
|
||||||
if (fps_n > 0) {
|
if (v4l2src->fps_n > 0) {
|
||||||
GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (GST_SECOND,
|
GST_BUFFER_DURATION (buf) =
|
||||||
fps_n, fps_d);
|
gst_util_uint64_scale_int (GST_SECOND, v4l2src->fps_n, v4l2src->fps_d);
|
||||||
} else {
|
} else {
|
||||||
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* G-Streamer Video4linux2 video-capture plugin - system calls
|
/* G-Streamer Video4linux2 video-capture plugin - system calls
|
||||||
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -48,7 +49,7 @@ gboolean gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
|
||||||
void gst_v4l2src_free_buffer (GstBuffer * buffer);
|
void gst_v4l2src_free_buffer (GstBuffer * buffer);
|
||||||
|
|
||||||
|
|
||||||
gboolean gst_v4l2src_get_fps (GstV4l2Src * v4l2src, gint * fps_n, gint * fps_d);
|
gboolean gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d);
|
||||||
|
|
||||||
GValue *gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src);
|
GValue *gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src);
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ main (int argc, char *argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv < 2) {
|
if (argc < 2) {
|
||||||
g_object_set (source, "device", "/dev/video0", NULL);
|
g_object_set (source, "device", "/dev/video0", NULL);
|
||||||
} else {
|
} else {
|
||||||
g_object_set (source, "device", argv[1], NULL);
|
g_object_set (source, "device", argv[1], NULL);
|
||||||
|
@ -222,7 +222,7 @@ main (int argc, char *argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv < 2)
|
if (argc < 2)
|
||||||
printf
|
printf
|
||||||
("\nOpening /dev/video0. Launch ./v4l2src-test.c devname to try another one\n");
|
("\nOpening /dev/video0. Launch ./v4l2src-test.c devname to try another one\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue