mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
v4l plugins: add open/close signals v4l2 plugins: add open/close signals move source format enumeration from v4l2elem...
Original commit message from CVS: v4l plugins: * add open/close signals v4l2 plugins: * add open/close signals * move source format enumeration from v4l2element to v4l2src * adapt to the final v4l2 API in kernel 2.5 (patches for 2.4 on http://bytesex.org/patches) * small tweaks
This commit is contained in:
parent
2c1d8f0814
commit
bcf4679ab3
9 changed files with 273 additions and 156 deletions
|
@ -37,6 +37,8 @@ static GstElementDetails gst_v4l2element_details = {
|
|||
/* V4l2Element signals and args */
|
||||
enum {
|
||||
/* FILL ME */
|
||||
SIGNAL_OPEN,
|
||||
SIGNAL_CLOSE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
@ -58,7 +60,7 @@ enum {
|
|||
ARG_DEVICE_NAME,
|
||||
ARG_DEVICE_HAS_CAPTURE,
|
||||
ARG_DEVICE_HAS_OVERLAY,
|
||||
ARG_DEVICE_HAS_CODEC,
|
||||
ARG_DEVICE_HAS_PLAYBACK,
|
||||
ARG_DISPLAY,
|
||||
ARG_VIDEOWINDOW,
|
||||
ARG_DO_OVERLAY,
|
||||
|
@ -79,7 +81,7 @@ static GstElementStateReturn gst_v4l2element_change_state (GstElement *
|
|||
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
/*static guint gst_v4l2element_signals[LAST_SIGNAL] = { 0 }; */
|
||||
static guint gst_v4l2element_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
GType
|
||||
|
@ -168,12 +170,12 @@ gst_v4l2element_class_init (GstV4l2ElementClass *klass)
|
|||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_HAS_CAPTURE,
|
||||
g_param_spec_boolean("can_capture","can_capture","can_capture",
|
||||
0,G_PARAM_READABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_HAS_PLAYBACK,
|
||||
g_param_spec_boolean("can_playback","can_playback","can_playback",
|
||||
0,G_PARAM_READABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_HAS_OVERLAY,
|
||||
g_param_spec_boolean("has_overlay","has_overlay","has_overlay",
|
||||
0,G_PARAM_READABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_HAS_CODEC,
|
||||
g_param_spec_boolean("has_compression","has_compression","has_compression",
|
||||
0,G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DISPLAY,
|
||||
g_param_spec_string("display","display","display",
|
||||
|
@ -185,6 +187,18 @@ gst_v4l2element_class_init (GstV4l2ElementClass *klass)
|
|||
g_param_spec_pointer("videowindow","videowindow","videowindow",
|
||||
G_PARAM_WRITABLE));
|
||||
|
||||
/* signals */
|
||||
gst_v4l2element_signals[SIGNAL_OPEN] =
|
||||
g_signal_new("open", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(GstV4l2ElementClass, open),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
gst_v4l2element_signals[SIGNAL_CLOSE] =
|
||||
g_signal_new("close", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(GstV4l2ElementClass, close),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
|
||||
gobject_class->set_property = gst_v4l2element_set_property;
|
||||
gobject_class->get_property = gst_v4l2element_get_property;
|
||||
|
||||
|
@ -206,7 +220,6 @@ gst_v4l2element_init (GstV4l2Element *v4l2element)
|
|||
v4l2element->frequency = 0;
|
||||
|
||||
v4l2element->controls = NULL;
|
||||
v4l2element->formats = NULL;
|
||||
v4l2element->outputs = NULL;
|
||||
v4l2element->inputs = NULL;
|
||||
v4l2element->norms = NULL;
|
||||
|
@ -277,7 +290,7 @@ gst_v4l2element_set_property (GObject *object,
|
|||
GByteArray *array = (GByteArray *) g_value_get_pointer(value);
|
||||
struct v4l2_clip *clips = (struct v4l2_clip *) array->data;
|
||||
gst_v4l2_set_window(v4l2element,
|
||||
clips->x, clips->y, clips->width, clips->height,
|
||||
clips->c.left, clips->c.top, clips->c.width, clips->c.height,
|
||||
&clips[1], array->len/sizeof(struct v4l2_clip)-1);
|
||||
}
|
||||
break;
|
||||
|
@ -342,8 +355,8 @@ gst_v4l2element_get_property (GObject *object,
|
|||
break;
|
||||
case ARG_HAS_TUNER:
|
||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
||||
temp_i = gst_v4l2_has_tuner(v4l2element);
|
||||
g_value_set_boolean(value, temp_i>0?TRUE:FALSE);
|
||||
g_value_set_boolean(value,
|
||||
gst_v4l2_has_tuner(v4l2element, &temp_i));
|
||||
break;
|
||||
case ARG_FREQUENCY:
|
||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
||||
|
@ -376,25 +389,25 @@ gst_v4l2element_get_property (GObject *object,
|
|||
break;
|
||||
case ARG_DEVICE_NAME:
|
||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
||||
g_value_set_string(value, g_strdup(v4l2element->vcap.name));
|
||||
g_value_set_string(value, g_strdup(v4l2element->vcap.card));
|
||||
break;
|
||||
case ARG_DEVICE_HAS_CAPTURE:
|
||||
if (GST_V4L2_IS_OPEN(v4l2element) &&
|
||||
(v4l2element->vcap.type == V4L2_TYPE_CODEC ||
|
||||
v4l2element->vcap.type == V4L2_TYPE_CAPTURE) &&
|
||||
v4l2element->vcap.flags & V4L2_FLAG_STREAMING)
|
||||
v4l2element->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE &&
|
||||
v4l2element->vcap.capabilities & V4L2_CAP_STREAMING)
|
||||
temp_i = 1;
|
||||
g_value_set_boolean(value, temp_i>0?TRUE:FALSE);
|
||||
break;
|
||||
case ARG_DEVICE_HAS_OVERLAY:
|
||||
if (GST_V4L2_IS_OPEN(v4l2element) &&
|
||||
v4l2element->vcap.flags & V4L2_FLAG_PREVIEW)
|
||||
v4l2element->vcap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
|
||||
temp_i = 1;
|
||||
g_value_set_boolean(value, temp_i>0?TRUE:FALSE);
|
||||
break;
|
||||
case ARG_DEVICE_HAS_CODEC:
|
||||
case ARG_DEVICE_HAS_PLAYBACK:
|
||||
if (GST_V4L2_IS_OPEN(v4l2element) &&
|
||||
v4l2element->vcap.type == V4L2_TYPE_CODEC)
|
||||
v4l2element->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT &&
|
||||
v4l2element->vcap.capabilities & V4L2_CAP_STREAMING)
|
||||
temp_i = 1;
|
||||
g_value_set_boolean(value, temp_i>0?TRUE:FALSE);
|
||||
break;
|
||||
|
@ -422,6 +435,11 @@ gst_v4l2element_change_state (GstElement *element)
|
|||
if (!gst_v4l2_open(v4l2element))
|
||||
return GST_STATE_FAILURE;
|
||||
|
||||
/* emit a signal! whoopie! */
|
||||
g_signal_emit(G_OBJECT(v4l2element),
|
||||
gst_v4l2element_signals[SIGNAL_OPEN], 0,
|
||||
v4l2element->device);
|
||||
|
||||
/* now, sync options */
|
||||
if (v4l2element->norm >= 0)
|
||||
if (!gst_v4l2_set_norm(v4l2element, v4l2element->norm))
|
||||
|
@ -439,6 +457,11 @@ gst_v4l2element_change_state (GstElement *element)
|
|||
case GST_STATE_READY_TO_NULL:
|
||||
if (!gst_v4l2_close(v4l2element))
|
||||
return GST_STATE_FAILURE;
|
||||
|
||||
/* emit yet another signal! wheehee! */
|
||||
g_signal_emit(G_OBJECT(v4l2element),
|
||||
gst_v4l2element_signals[SIGNAL_CLOSE], 0,
|
||||
v4l2element->device);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,21 +41,17 @@
|
|||
typedef struct _GstV4l2Element GstV4l2Element;
|
||||
typedef struct _GstV4l2ElementClass GstV4l2ElementClass;
|
||||
|
||||
typedef struct _GstV4l2Rect {
|
||||
gint x, y, w, h;
|
||||
} GstV4l2Rect;
|
||||
|
||||
typedef enum {
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_INT,
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_BOOLEAN,
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_BUTTON,
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_LIST,
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_INTEGER = V4L2_CTRL_TYPE_INTEGER,
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_BOOLEAN = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_MENU = V4L2_CTRL_TYPE_MENU,
|
||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_BUTTON = V4L2_CTRL_TYPE_BUTTON,
|
||||
} GstV4l2AttributeValueType;
|
||||
|
||||
typedef enum {
|
||||
GST_V4L2_ATTRIBUTE_TYPE_VIDEO,
|
||||
GST_V4L2_ATTRIBUTE_TYPE_AUDIO,
|
||||
GST_V4L2_ATTRIBUTE_TYPE_EFFECT,
|
||||
GST_V4L2_ATTRIBUTE_TYPE_OTHER,
|
||||
} GstV4l2AttributeType;
|
||||
|
||||
typedef struct _GstV4l2Attribute {
|
||||
|
@ -83,7 +79,6 @@ struct _GstV4l2Element {
|
|||
struct v4l2_capability vcap;
|
||||
|
||||
/* the toys available to us */
|
||||
GList /*v4l2_fmtdesc*/ *formats; /* list of available capture formats */
|
||||
GList /*v4l2_input*/ *inputs;
|
||||
GList /*v4l2_output*/ *outputs;
|
||||
GList /*v4l2_enumstd*/ *norms;
|
||||
|
@ -99,6 +94,12 @@ struct _GstV4l2Element {
|
|||
|
||||
struct _GstV4l2ElementClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*open) (GstElement *element,
|
||||
const gchar *device);
|
||||
void (*close) (GstElement *element,
|
||||
const gchar *device);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -56,6 +56,12 @@ enum {
|
|||
static void gst_v4l2src_class_init (GstV4l2SrcClass *klass);
|
||||
static void gst_v4l2src_init (GstV4l2Src *v4l2src);
|
||||
|
||||
/* signal functions */
|
||||
static void gst_v4l2src_open (GstElement *element,
|
||||
const gchar *device);
|
||||
static void gst_v4l2src_close (GstElement *element,
|
||||
const gchar *device);
|
||||
|
||||
/* pad/buffer functions */
|
||||
static gboolean gst_v4l2src_srcconvert (GstPad *pad,
|
||||
GstFormat src_format,
|
||||
|
@ -127,9 +133,11 @@ gst_v4l2src_class_init (GstV4l2SrcClass *klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstV4l2ElementClass *v4l2_class;
|
||||
|
||||
gobject_class = (GObjectClass*)klass;
|
||||
gstelement_class = (GstElementClass*)klass;
|
||||
v4l2_class = (GstV4l2ElementClass*)klass;
|
||||
|
||||
parent_class = g_type_class_ref(GST_TYPE_V4L2ELEMENT);
|
||||
|
||||
|
@ -164,6 +172,9 @@ gst_v4l2src_class_init (GstV4l2SrcClass *klass)
|
|||
gobject_class->get_property = gst_v4l2src_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_v4l2src_change_state;
|
||||
|
||||
v4l2_class->open = gst_v4l2src_open;
|
||||
v4l2_class->close = gst_v4l2src_close;
|
||||
}
|
||||
|
||||
|
||||
|
@ -188,6 +199,24 @@ gst_v4l2src_init (GstV4l2Src *v4l2src)
|
|||
v4l2src->width = 160;
|
||||
v4l2src->height = 120;
|
||||
v4l2src->breq.count = 0;
|
||||
|
||||
v4l2src->formats = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_v4l2src_open (GstElement *element,
|
||||
const gchar *device)
|
||||
{
|
||||
gst_v4l2src_fill_format_list(GST_V4L2SRC(element));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_v4l2src_close (GstElement *element,
|
||||
const gchar *device)
|
||||
{
|
||||
gst_v4l2src_empty_format_list(GST_V4L2SRC(element));
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,8 +240,8 @@ gst_v4l2src_srcconvert (GstPad *pad,
|
|||
if (!gst_v4l2_get_norm(GST_V4L2ELEMENT(v4l2src), &norm))
|
||||
return FALSE;
|
||||
|
||||
std = &((struct v4l2_enumstd *) g_list_nth_data(GST_V4L2ELEMENT(v4l2src)->norms, norm))->std;
|
||||
fps = std->framerate.numerator / std->framerate.denominator;
|
||||
std = ((struct v4l2_standard *) g_list_nth_data(GST_V4L2ELEMENT(v4l2src)->norms, norm));
|
||||
fps = std->frameperiod.numerator / std->frameperiod.denominator;
|
||||
|
||||
switch (src_format) {
|
||||
case GST_FORMAT_TIME:
|
||||
|
@ -453,8 +482,8 @@ gst_v4l2_caps_to_v4l2fourcc (GstV4l2Src *v4l2src,
|
|||
break; }
|
||||
}
|
||||
|
||||
for (i=0;i<g_list_length(GST_V4L2ELEMENT(v4l2src)->formats);i++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(GST_V4L2ELEMENT(v4l2src)->formats, i);
|
||||
for (i=0;i<g_list_length(v4l2src->formats);i++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, i);
|
||||
if (fmt->pixelformat == fourcc)
|
||||
fourcclist = g_list_append(fourcclist, (gpointer)fourcc);
|
||||
}
|
||||
|
@ -585,8 +614,8 @@ gst_v4l2src_srcconnect (GstPad *pad,
|
|||
for (i=0;i<g_list_length(fourccs);i++) {
|
||||
guint32 fourcc = (guint32)g_list_nth_data(fourccs, i);
|
||||
gint n;
|
||||
for (n=0;n<g_list_length(v4l2element->formats);n++) {
|
||||
struct v4l2_fmtdesc *format = g_list_nth_data(v4l2element->formats, n);
|
||||
for (n=0;n<g_list_length(v4l2src->formats);n++) {
|
||||
struct v4l2_fmtdesc *format = g_list_nth_data(v4l2src->formats, n);
|
||||
if (format->pixelformat == fourcc) {
|
||||
/* we found the pixelformat! - try it out */
|
||||
if (gst_v4l2src_set_capture(v4l2src, format,
|
||||
|
@ -631,15 +660,15 @@ gst_v4l2src_getcaps (GstPad *pad,
|
|||
|
||||
/* build our own capslist */
|
||||
if (v4l2src->palette) {
|
||||
struct v4l2_fmtdesc *format = g_list_nth_data(v4l2element->formats, v4l2src->palette);
|
||||
struct v4l2_fmtdesc *format = g_list_nth_data(v4l2src->formats, v4l2src->palette);
|
||||
owncapslist = gst_v4l2src_v4l2fourcc_to_caps(format->pixelformat,
|
||||
v4l2src->width, v4l2src->height,
|
||||
format->flags & V4L2_FMT_FLAG_COMPRESSED);
|
||||
} else {
|
||||
gint i;
|
||||
owncapslist = NULL;
|
||||
for (i=0;i<g_list_length(v4l2element->formats);i++) {
|
||||
struct v4l2_fmtdesc *format = g_list_nth_data(v4l2element->formats, i);
|
||||
for (i=0;i<g_list_length(v4l2src->formats);i++) {
|
||||
struct v4l2_fmtdesc *format = g_list_nth_data(v4l2src->formats, i);
|
||||
caps = gst_v4l2src_v4l2fourcc_to_caps(format->pixelformat,
|
||||
v4l2src->width, v4l2src->height,
|
||||
format->flags & V4L2_FMT_FLAG_COMPRESSED);
|
||||
|
@ -675,7 +704,8 @@ gst_v4l2src_get (GstPad *pad)
|
|||
GST_BUFFER_DATA(buf) = GST_V4L2ELEMENT(v4l2src)->buffer[num];
|
||||
GST_BUFFER_SIZE(buf) = v4l2src->bufsettings.bytesused;
|
||||
if (!v4l2src->first_timestamp)
|
||||
v4l2src->first_timestamp = v4l2src->bufsettings.timestamp;
|
||||
v4l2src->first_timestamp = v4l2src->bufsettings.timestamp.tv_sec * GST_SECOND +
|
||||
v4l2src->bufsettings.timestamp.tv_usec * (GST_SECOND/1000000);
|
||||
GST_BUFFER_TIMESTAMP(buf) = v4l2src->bufsettings.length - v4l2src->first_timestamp;
|
||||
|
||||
return buf;
|
||||
|
@ -717,8 +747,8 @@ gst_v4l2src_set_property (GObject *object,
|
|||
gint i;
|
||||
const gchar *formatstr = g_value_get_string(value);
|
||||
guint32 fourcc = GST_MAKE_FOURCC(formatstr[0],formatstr[1],formatstr[2],formatstr[3]);
|
||||
for (i=0;i<g_list_length(GST_V4L2ELEMENT(v4l2src)->formats);i++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(GST_V4L2ELEMENT(v4l2src)->formats, i);
|
||||
for (i=0;i<g_list_length(v4l2src->formats);i++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, i);
|
||||
if (fmt->pixelformat == fourcc)
|
||||
v4l2src->palette = i;
|
||||
}
|
||||
|
@ -767,7 +797,7 @@ gst_v4l2src_get_property (GObject *object,
|
|||
break;
|
||||
|
||||
case ARG_FOURCC: {
|
||||
struct v4l2_fmtdesc *fmt = g_list_nth_data(GST_V4L2ELEMENT(v4l2src)->formats, v4l2src->palette);
|
||||
struct v4l2_fmtdesc *fmt = g_list_nth_data(v4l2src->formats, v4l2src->palette);
|
||||
guint32 print_format = GUINT32_FROM_LE(fmt->pixelformat);
|
||||
gchar *print_format_str = (gchar *) &print_format;
|
||||
g_value_set_string(value, g_strndup(print_format_str, 4));
|
||||
|
|
|
@ -44,11 +44,14 @@ struct _GstV4l2Src {
|
|||
/* pads */
|
||||
GstPad *srcpad;
|
||||
|
||||
/* internal lists */
|
||||
GList /*v4l2_fmtdesc*/ *formats; /* list of available capture formats */
|
||||
|
||||
/* buffer properties */
|
||||
struct v4l2_buffer bufsettings;
|
||||
struct v4l2_requestbuffers breq;
|
||||
struct v4l2_format format;
|
||||
stamp_t first_timestamp;
|
||||
guint64 first_timestamp;
|
||||
|
||||
/* bufferpool for the buffers we're gonna use */
|
||||
GstBufferPool *bufferpool;
|
||||
|
|
|
@ -89,21 +89,23 @@ gst_v4l2_set_window (GstV4l2Element *v4l2element,
|
|||
struct v4l2_clip *clips,
|
||||
gint num_clips)
|
||||
{
|
||||
struct v4l2_window vwin;
|
||||
struct v4l2_format fmt;
|
||||
|
||||
DEBUG("trying to set video window to %dx%d,%d,%d", x,y,w,h);
|
||||
GST_V4L2_CHECK_OVERLAY(v4l2element);
|
||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||
|
||||
vwin.clipcount = 0;
|
||||
vwin.x = x;
|
||||
vwin.y = y;
|
||||
vwin.width = w;
|
||||
vwin.height = h;
|
||||
vwin.clips = clips;
|
||||
vwin.clipcount = num_clips;
|
||||
fmt.type = V4L2_CAP_VIDEO_OVERLAY;
|
||||
fmt.fmt.win.clipcount = 0;
|
||||
fmt.fmt.win.w.left = x;
|
||||
fmt.fmt.win.w.top = y;
|
||||
fmt.fmt.win.w.width = w;
|
||||
fmt.fmt.win.w.height = h;
|
||||
fmt.fmt.win.clips = clips;
|
||||
fmt.fmt.win.clipcount = num_clips;
|
||||
fmt.fmt.win.bitmap = NULL;
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_S_WIN, &vwin) < 0) {
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_S_FMT, &fmt) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to set the video window on device %s: %s",
|
||||
v4l2element->device, g_strerror(errno));
|
||||
|
@ -130,7 +132,7 @@ gst_v4l2_enable_overlay (GstV4l2Element *v4l2element,
|
|||
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||
GST_V4L2_CHECK_OVERLAY(v4l2element);
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_PREVIEW, &doit) < 0) {
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_OVERLAY, &doit) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to %s overlay display for device %s: %s",
|
||||
enable?"enable":"disable", v4l2element->device, g_strerror(errno));
|
||||
|
|
|
@ -73,25 +73,6 @@ gst_v4l2_fill_lists (GstV4l2Element *v4l2element)
|
|||
DEBUG("getting enumerations");
|
||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||
|
||||
/* create enumeration lists - let's start with format enumeration */
|
||||
for (n=0;;n++) {
|
||||
struct v4l2_fmtdesc format, *fmtptr;
|
||||
format.index = n;
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_ENUM_PIXFMT, &format) < 0) {
|
||||
if (errno == EINVAL)
|
||||
break; /* end of enumeration */
|
||||
else {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to get no. %d in pixelformat enumeration for %s: %s",
|
||||
n, v4l2element->device, g_strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fmtptr = g_malloc(sizeof(format));
|
||||
memcpy(fmtptr, &format, sizeof(format));
|
||||
v4l2element->formats = g_list_append(v4l2element->formats, fmtptr);
|
||||
}
|
||||
|
||||
/* and now, the inputs */
|
||||
for (n=0;;n++) {
|
||||
struct v4l2_input input, *inpptr;
|
||||
|
@ -132,7 +113,7 @@ gst_v4l2_fill_lists (GstV4l2Element *v4l2element)
|
|||
|
||||
/* norms... */
|
||||
for (n=0;;n++) {
|
||||
struct v4l2_enumstd standard, *stdptr;
|
||||
struct v4l2_standard standard, *stdptr;
|
||||
standard.index = n;
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_ENUMSTD, &standard) < 0) {
|
||||
if (errno == EINVAL)
|
||||
|
@ -150,20 +131,28 @@ gst_v4l2_fill_lists (GstV4l2Element *v4l2element)
|
|||
}
|
||||
|
||||
/* and lastly, controls+menus (if appropriate) */
|
||||
for (n=0;;n++) {
|
||||
for (n=V4L2_CID_BASE;;n++) {
|
||||
struct v4l2_queryctrl control, *ctrlptr;
|
||||
GList *menus = NULL;
|
||||
/* hacky... */
|
||||
if (n == V4L2_CID_LASTP1)
|
||||
n = V4L2_CID_PRIVATE_BASE;
|
||||
control.id = n;
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_QUERYCTRL, &control) < 0) {
|
||||
if (errno == EINVAL)
|
||||
break; /* end of enumeration */
|
||||
else {
|
||||
if (errno == EINVAL) {
|
||||
if (n < V4L2_CID_PRIVATE_BASE)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
} else {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to get no. %d in control enumeration for %s: %s",
|
||||
n, v4l2element->device, g_strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (control.flags & V4L2_CTRL_FLAG_DISABLED)
|
||||
continue;
|
||||
ctrlptr = g_malloc(sizeof(control));
|
||||
memcpy(ctrlptr, &control, sizeof(control));
|
||||
v4l2element->controls = g_list_append(v4l2element->controls, ctrlptr);
|
||||
|
@ -216,11 +205,6 @@ gst_v4l2_empty_lists (GstV4l2Element *v4l2element)
|
|||
v4l2element->norms = g_list_remove(v4l2element->norms, data);
|
||||
g_free(data);
|
||||
}
|
||||
while (g_list_length(v4l2element->formats) > 0) {
|
||||
gpointer data = g_list_nth_data(v4l2element->formats, 0);
|
||||
v4l2element->formats = g_list_remove(v4l2element->formats, data);
|
||||
g_free(data);
|
||||
}
|
||||
while (g_list_length(v4l2element->controls) > 0) {
|
||||
gpointer data = g_list_nth_data(v4l2element->controls, 0);
|
||||
v4l2element->controls = g_list_remove(v4l2element->controls, data);
|
||||
|
@ -275,7 +259,7 @@ gst_v4l2_open (GstV4l2Element *v4l2element)
|
|||
goto error;
|
||||
|
||||
gst_info("Opened device '%s' (%s) successfully\n",
|
||||
v4l2element->vcap.name, v4l2element->device);
|
||||
v4l2element->vcap.card, v4l2element->device);
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
@ -326,13 +310,13 @@ gboolean
|
|||
gst_v4l2_get_norm (GstV4l2Element *v4l2element,
|
||||
gint *norm)
|
||||
{
|
||||
struct v4l2_standard standard;
|
||||
v4l2_std_id std_id;
|
||||
gint n;
|
||||
|
||||
DEBUG("getting norm");
|
||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_STD, &standard) < 0) {
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_STD, &std_id) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to get the current norm for device %s: %s",
|
||||
v4l2element->device, g_strerror(errno));
|
||||
|
@ -341,16 +325,16 @@ gst_v4l2_get_norm (GstV4l2Element *v4l2element,
|
|||
|
||||
/* try to find out what norm number this actually is */
|
||||
for (n=0;n<g_list_length(v4l2element->norms);n++) {
|
||||
struct v4l2_enumstd *stdptr = (struct v4l2_enumstd *) g_list_nth_data(v4l2element->norms, n);
|
||||
if (!strcmp(stdptr->std.name, standard.name)) {
|
||||
struct v4l2_standard *stdptr = (struct v4l2_standard *) g_list_nth_data(v4l2element->norms, n);
|
||||
if (stdptr->id == std_id) {
|
||||
*norm = n;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to find norm '%s' in our list of available norms for device %s",
|
||||
standard.name, v4l2element->device);
|
||||
"Failed to find norm '%llu' in our list of available norms for device %s",
|
||||
std_id, v4l2element->device);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -365,7 +349,7 @@ gboolean
|
|||
gst_v4l2_set_norm (GstV4l2Element *v4l2element,
|
||||
gint norm)
|
||||
{
|
||||
struct v4l2_enumstd *standard;
|
||||
struct v4l2_standard *standard;
|
||||
|
||||
DEBUG("trying to set norm to %d", norm);
|
||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||
|
@ -378,12 +362,12 @@ gst_v4l2_set_norm (GstV4l2Element *v4l2element,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
standard = (struct v4l2_enumstd *) g_list_nth_data(v4l2element->norms, norm);
|
||||
standard = (struct v4l2_standard *) g_list_nth_data(v4l2element->norms, norm);
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_S_STD, &standard->std) < 0) {
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_S_STD, &standard->id) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to set norm '%s' (%d) for device %s: %s",
|
||||
standard->std.name, norm, v4l2element->device, g_strerror(errno));
|
||||
"Failed to set norm '%s' (%llu) for device %s: %s",
|
||||
standard->name, standard->id, v4l2element->device, g_strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -406,8 +390,8 @@ gst_v4l2_get_norm_names (GstV4l2Element *v4l2element)
|
|||
DEBUG("getting a list of norm names");
|
||||
|
||||
for (n=0;n<g_list_length(v4l2element->norms);n++) {
|
||||
struct v4l2_enumstd *standard = (struct v4l2_enumstd *) g_list_nth_data(v4l2element->norms, n);
|
||||
names = g_list_append(names, g_strdup(standard->std.name));
|
||||
struct v4l2_standard *standard = (struct v4l2_standard *) g_list_nth_data(v4l2element->norms, n);
|
||||
names = g_list_append(names, g_strdup(standard->name));
|
||||
}
|
||||
|
||||
return names;
|
||||
|
@ -586,8 +570,9 @@ gst_v4l2_get_output_names (GstV4l2Element *v4l2element)
|
|||
* return value: TRUE if it has a tuner, else FALSE
|
||||
******************************************************/
|
||||
|
||||
gboolean
|
||||
gst_v4l2_has_tuner (GstV4l2Element *v4l2element)
|
||||
gint
|
||||
gst_v4l2_has_tuner (GstV4l2Element *v4l2element,
|
||||
gint *tuner_num)
|
||||
{
|
||||
gint input_num;
|
||||
struct v4l2_input *input;
|
||||
|
@ -600,8 +585,12 @@ gst_v4l2_has_tuner (GstV4l2Element *v4l2element)
|
|||
|
||||
input = (struct v4l2_input *) g_list_nth_data(v4l2element->inputs, input_num);
|
||||
|
||||
return (input->type == V4L2_INPUT_TYPE_TUNER &&
|
||||
v4l2element->vcap.flags & V4L2_FLAG_TUNER);
|
||||
if (input->type == V4L2_INPUT_TYPE_TUNER &&
|
||||
v4l2element->vcap.capabilities & V4L2_CAP_TUNER) {
|
||||
*tuner_num = input->tuner;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -615,22 +604,24 @@ gboolean
|
|||
gst_v4l2_get_frequency (GstV4l2Element *v4l2element,
|
||||
gulong *frequency)
|
||||
{
|
||||
gint n;
|
||||
struct v4l2_frequency freq;
|
||||
|
||||
DEBUG("getting current tuner frequency");
|
||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||
|
||||
if (!gst_v4l2_has_tuner(v4l2element))
|
||||
if (!gst_v4l2_has_tuner(v4l2element, &freq.tuner))
|
||||
return FALSE;
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_FREQ, &n) < 0) {
|
||||
freq.type = 0;
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_FREQUENCY, &freq) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to get current tuner frequency for device %s: %s",
|
||||
v4l2element->device, g_strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*frequency = n;
|
||||
*frequency = freq.frequency;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -646,16 +637,19 @@ gboolean
|
|||
gst_v4l2_set_frequency (GstV4l2Element *v4l2element,
|
||||
gulong frequency)
|
||||
{
|
||||
gint n = frequency;
|
||||
struct v4l2_frequency freq;
|
||||
|
||||
DEBUG("setting current tuner frequency to %lu", frequency);
|
||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||
GST_V4L2_CHECK_NOT_ACTIVE(v4l2element);
|
||||
|
||||
if (!gst_v4l2_has_tuner(v4l2element))
|
||||
if (!gst_v4l2_has_tuner(v4l2element, &freq.tuner))
|
||||
return FALSE;
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_FREQ, &n) < 0) {
|
||||
freq.frequency = frequency;
|
||||
freq.type = 0;
|
||||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_FREQUENCY, &freq) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to set tuner frequency to %lu for device %s: %s",
|
||||
frequency, v4l2element->device, g_strerror(errno));
|
||||
|
@ -683,7 +677,7 @@ gst_v4l2_signal_strength (GstV4l2Element *v4l2element,
|
|||
|
||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_TUNER, &tuner) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2element),
|
||||
"Failed to set signal strength for device %s: %s",
|
||||
"Failed to get signal strength for device %s: %s",
|
||||
v4l2element->device, g_strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -714,7 +708,7 @@ gst_v4l2_has_audio (GstV4l2Element *v4l2element)
|
|||
|
||||
input = (struct v4l2_input *) g_list_nth_data(v4l2element->inputs, input_num);
|
||||
|
||||
return (input->capability & V4L2_INPUT_CAP_AUDIO);
|
||||
return (input->audioset != 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -738,36 +732,47 @@ gst_v4l2_get_attributes (GstV4l2Element *v4l2element)
|
|||
attribute->name = g_strdup(control->name);
|
||||
attribute->index = i;
|
||||
attribute->list_items = NULL;
|
||||
switch (control->type) {
|
||||
case V4L2_CTRL_TYPE_INTEGER:
|
||||
attribute->val_type = GST_V4L2_ATTRIBUTE_VALUE_TYPE_INT;
|
||||
break;
|
||||
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||
attribute->val_type = GST_V4L2_ATTRIBUTE_VALUE_TYPE_BOOLEAN;
|
||||
break;
|
||||
case V4L2_CTRL_TYPE_MENU: {
|
||||
/* list items */
|
||||
gint n;
|
||||
GList *menus = (GList *) g_list_nth_data(v4l2element->menus, i);
|
||||
for (n=0;n<g_list_length(menus);n++) {
|
||||
struct v4l2_querymenu *menu = g_list_nth_data(menus, n);
|
||||
attribute->list_items = g_list_append(attribute->list_items, g_strdup(menu->name));
|
||||
}
|
||||
attribute->val_type = GST_V4L2_ATTRIBUTE_VALUE_TYPE_LIST;
|
||||
break; }
|
||||
case V4L2_CTRL_TYPE_BUTTON:
|
||||
attribute->val_type = GST_V4L2_ATTRIBUTE_VALUE_TYPE_BUTTON;
|
||||
break;
|
||||
attribute->val_type = control->type;
|
||||
if (control->type == V4L2_CTRL_TYPE_MENU) {
|
||||
/* list items */
|
||||
gint n;
|
||||
GList *menus = (GList *) g_list_nth_data(v4l2element->menus, i);
|
||||
for (n=0;n<g_list_length(menus);n++) {
|
||||
struct v4l2_querymenu *menu = g_list_nth_data(menus, n);
|
||||
attribute->list_items = g_list_append(attribute->list_items,
|
||||
g_strdup(menu->name));
|
||||
}
|
||||
}
|
||||
switch (control->category) {
|
||||
case V4L2_CTRL_CAT_VIDEO:
|
||||
switch (control->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
case V4L2_CID_CONTRAST:
|
||||
case V4L2_CID_SATURATION:
|
||||
case V4L2_CID_HUE:
|
||||
case V4L2_CID_BLACK_LEVEL:
|
||||
case V4L2_CID_AUTO_WHITE_BALANCE:
|
||||
case V4L2_CID_DO_WHITE_BALANCE:
|
||||
case V4L2_CID_RED_BALANCE:
|
||||
case V4L2_CID_BLUE_BALANCE:
|
||||
case V4L2_CID_GAMMA:
|
||||
case V4L2_CID_EXPOSURE:
|
||||
case V4L2_CID_AUTOGAIN:
|
||||
case V4L2_CID_GAIN:
|
||||
case V4L2_CID_HFLIP:
|
||||
case V4L2_CID_VFLIP:
|
||||
case V4L2_CID_HCENTER:
|
||||
case V4L2_CID_VCENTER:
|
||||
attribute->type = GST_V4L2_ATTRIBUTE_TYPE_VIDEO;
|
||||
break;
|
||||
case V4L2_CTRL_CAT_AUDIO:
|
||||
case V4L2_CID_AUDIO_VOLUME:
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
case V4L2_CID_AUDIO_BASS:
|
||||
case V4L2_CID_AUDIO_TREBLE:
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
case V4L2_CID_AUDIO_LOUDNESS:
|
||||
attribute->type = GST_V4L2_ATTRIBUTE_TYPE_AUDIO;
|
||||
break;
|
||||
case V4L2_CTRL_CAT_EFFECT:
|
||||
attribute->type = GST_V4L2_ATTRIBUTE_TYPE_EFFECT;
|
||||
default:
|
||||
attribute->type = GST_V4L2_ATTRIBUTE_TYPE_OTHER;
|
||||
break;
|
||||
}
|
||||
gst_v4l2_get_attribute(v4l2element, i, &attribute->value);
|
||||
|
|
|
@ -32,11 +32,11 @@
|
|||
(v4l2element->buffer != NULL)
|
||||
|
||||
#define GST_V4L2_IS_OVERLAY(v4l2element) \
|
||||
(v4l2element->vcap.flags & V4L2_FLAG_PREVIEW)
|
||||
(v4l2element->vcap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
|
||||
|
||||
/* checks whether the current v4lelement has already been open()'ed or not */
|
||||
#define GST_V4L2_CHECK_OPEN(v4l2element) \
|
||||
if (v4l2element->video_fd <= 0) \
|
||||
if (!GST_V4L2_IS_OPEN(v4l2element)) \
|
||||
{ \
|
||||
gst_element_error(GST_ELEMENT(v4l2element), \
|
||||
"Device is not open"); \
|
||||
|
@ -45,7 +45,7 @@
|
|||
|
||||
/* checks whether the current v4lelement is close()'ed or whether it is still open */
|
||||
#define GST_V4L2_CHECK_NOT_OPEN(v4l2element) \
|
||||
if (v4l2element->video_fd != -1) \
|
||||
if (GST_V4L2_IS_OPEN(v4l2element)) \
|
||||
{ \
|
||||
gst_element_error(GST_ELEMENT(v4l2element), \
|
||||
"Device is open"); \
|
||||
|
@ -54,16 +54,16 @@
|
|||
|
||||
/* checks whether the current v4lelement does video overlay */
|
||||
#define GST_V4L2_CHECK_OVERLAY(v4l2element) \
|
||||
if (!(v4l2element->vcap.flags & V4L2_FLAG_PREVIEW)) \
|
||||
{ \
|
||||
gst_element_error(GST_ELEMENT(v4l2element), \
|
||||
"Device doesn't do overlay"); \
|
||||
return FALSE; \
|
||||
if (!GST_V4L2_IS_OVERLAY(v4l2element)) \
|
||||
{ \
|
||||
gst_element_error(GST_ELEMENT(v4l2element), \
|
||||
"Device doesn't do overlay"); \
|
||||
return FALSE; \
|
||||
}
|
||||
|
||||
/* checks whether we're in capture mode or not */
|
||||
#define GST_V4L2_CHECK_ACTIVE(v4l2element) \
|
||||
if (v4l2element->buffer == NULL) \
|
||||
if (!GST_V4L2_IS_ACTIVE(v4l2element)) \
|
||||
{ \
|
||||
gst_element_error(GST_ELEMENT(v4l2element), \
|
||||
"Device is not in streaming mode"); \
|
||||
|
@ -72,7 +72,7 @@
|
|||
|
||||
/* checks whether we're out of capture mode or not */
|
||||
#define GST_V4L2_CHECK_NOT_ACTIVE(v4l2element) \
|
||||
if (v4l2element->buffer != NULL) \
|
||||
if (GST_V4L2_IS_ACTIVE(v4l2element)) \
|
||||
{ \
|
||||
gst_element_error(GST_ELEMENT(v4l2element), \
|
||||
"Device is in streaming mode"); \
|
||||
|
@ -102,7 +102,8 @@ gboolean gst_v4l2_set_output (GstV4l2Element *v4l2element,
|
|||
GList * gst_v4l2_get_output_names (GstV4l2Element *v4l2element);
|
||||
|
||||
/* frequency control */
|
||||
gboolean gst_v4l2_has_tuner (GstV4l2Element *v4l2element);
|
||||
gboolean gst_v4l2_has_tuner (GstV4l2Element *v4l2element,
|
||||
gint *tuner_num);
|
||||
gboolean gst_v4l2_get_frequency (GstV4l2Element *v4l2element,
|
||||
gulong *frequency);
|
||||
gboolean gst_v4l2_set_frequency (GstV4l2Element *v4l2element,
|
||||
|
|
|
@ -41,6 +41,62 @@
|
|||
#endif
|
||||
|
||||
|
||||
/******************************************************
|
||||
* gst_v4l2src_fill_format_list():
|
||||
* create list of supported capture formats
|
||||
* return value: TRUE on success, FALSE on error
|
||||
******************************************************/
|
||||
|
||||
gboolean
|
||||
gst_v4l2src_fill_format_list (GstV4l2Src *v4l2src)
|
||||
{
|
||||
gint n;
|
||||
|
||||
DEBUG("getting src format enumerations");
|
||||
|
||||
/* format enumeration */
|
||||
for (n=0;;n++) {
|
||||
struct v4l2_fmtdesc format, *fmtptr;
|
||||
format.index = n;
|
||||
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (ioctl(GST_V4L2ELEMENT(v4l2src)->video_fd, VIDIOC_ENUM_FMT, &format) < 0) {
|
||||
if (errno == EINVAL)
|
||||
break; /* end of enumeration */
|
||||
else {
|
||||
gst_element_error(GST_ELEMENT(v4l2src),
|
||||
"Failed to get no. %d in pixelformat enumeration for %s: %s",
|
||||
n, GST_V4L2ELEMENT(v4l2src)->device, g_strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fmtptr = g_malloc(sizeof(format));
|
||||
memcpy(fmtptr, &format, sizeof(format));
|
||||
v4l2src->formats = g_list_append(v4l2src->formats, fmtptr);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* gst_v4l2src_empty_format_list():
|
||||
* free list of supported capture formats
|
||||
* return value: TRUE on success, FALSE on error
|
||||
******************************************************/
|
||||
|
||||
gboolean
|
||||
gst_v4l2src_empty_format_list (GstV4l2Src *v4l2src)
|
||||
{
|
||||
while (g_list_length(v4l2src->formats) > 0) {
|
||||
gpointer data = g_list_nth_data(v4l2src->formats, 0);
|
||||
v4l2src->formats = g_list_remove(v4l2src->formats, data);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* gst_v4l2src_queue_frame():
|
||||
* queue a frame for capturing
|
||||
|
@ -101,6 +157,7 @@ gst_v4l2src_get_capture (GstV4l2Src *v4l2src)
|
|||
|
||||
GST_V4L2_CHECK_OPEN(GST_V4L2ELEMENT(v4l2src));
|
||||
|
||||
v4l2src->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (ioctl(GST_V4L2ELEMENT(v4l2src)->video_fd, VIDIOC_G_FMT, &v4l2src->format) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2src),
|
||||
"Failed to get pixel format for device %s: %s",
|
||||
|
@ -134,12 +191,7 @@ gst_v4l2src_set_capture (GstV4l2Src *v4l2src,
|
|||
v4l2src->format.fmt.pix.width = width;
|
||||
v4l2src->format.fmt.pix.height = height;
|
||||
v4l2src->format.fmt.pix.pixelformat = fmt->pixelformat;
|
||||
if (fmt->flags & V4L2_FMT_FLAG_COMPRESSED) {
|
||||
v4l2src->format.fmt.pix.flags = V4L2_FMT_FLAG_COMPRESSED;
|
||||
v4l2src->format.type = V4L2_BUF_TYPE_CODECIN;
|
||||
} else {
|
||||
v4l2src->format.type = V4L2_BUF_TYPE_CAPTURE;
|
||||
}
|
||||
v4l2src->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
||||
if (ioctl(GST_V4L2ELEMENT(v4l2src)->video_fd, VIDIOC_S_FMT, &v4l2src->format) < 0) {
|
||||
gst_element_error(GST_ELEMENT(v4l2src),
|
||||
|
@ -189,8 +241,8 @@ gst_v4l2src_capture_init (GstV4l2Src *v4l2src)
|
|||
}
|
||||
v4l2src->bufsettings.type = v4l2src->format.type;
|
||||
|
||||
for (n=0;n<g_list_length(GST_V4L2ELEMENT(v4l2src)->formats);n++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(GST_V4L2ELEMENT(v4l2src)->formats, n);
|
||||
for (n=0;n<g_list_length(v4l2src->formats);n++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, n);
|
||||
if (v4l2src->format.fmt.pix.pixelformat == fmt->pixelformat) {
|
||||
desc = fmt->description;
|
||||
break;
|
||||
|
@ -359,11 +411,10 @@ GList *
|
|||
gst_v4l2src_get_fourcc_list (GstV4l2Src *v4l2src)
|
||||
{
|
||||
GList *list = NULL;
|
||||
GstV4l2Element *v4l2element = GST_V4L2ELEMENT(v4l2src);
|
||||
gint n;
|
||||
|
||||
for (n=0;n<g_list_length(v4l2element->formats);n++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2element->formats, n);
|
||||
for (n=0;n<g_list_length(v4l2src->formats);n++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, n);
|
||||
guint32 print_format = GUINT32_FROM_LE(fmt->pixelformat);
|
||||
gchar *print_format_str = (gchar *) &print_format;
|
||||
|
||||
|
@ -384,11 +435,10 @@ GList *
|
|||
gst_v4l2src_get_format_list (GstV4l2Src *v4l2src)
|
||||
{
|
||||
GList *list = NULL;
|
||||
GstV4l2Element *v4l2element = GST_V4L2ELEMENT(v4l2src);
|
||||
gint n;
|
||||
|
||||
for (n=0;n<g_list_length(v4l2element->formats);n++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2element->formats, n);
|
||||
for (n=0;n<g_list_length(v4l2src->formats);n++) {
|
||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, n);
|
||||
|
||||
list = g_list_append(list, g_strdup(fmt->description));
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ gboolean gst_v4l2src_requeue_frame (GstV4l2Src *v4l2src,
|
|||
gboolean gst_v4l2src_capture_stop (GstV4l2Src *v4l2src);
|
||||
gboolean gst_v4l2src_capture_deinit (GstV4l2Src *v4l2src);
|
||||
|
||||
gboolean gst_v4l2src_fill_format_list (GstV4l2Src *v4l2src);
|
||||
gboolean gst_v4l2src_empty_format_list (GstV4l2Src *v4l2src);
|
||||
GList * gst_v4l2src_get_fourcc_list (GstV4l2Src *v4l2src);
|
||||
GList * gst_v4l2src_get_format_list (GstV4l2Src *v4l2src);
|
||||
|
||||
|
|
Loading…
Reference in a new issue