static void gst_v4lsrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstV4lSrc *v4lsrc = GST_V4LSRC (object); switch (prop_id) { case PROP_AUTOPROBE: g_return_if_fail (!GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lsrc))); v4lsrc->autoprobe = g_value_get_boolean (value); break; case PROP_AUTOPROBE_FPS: g_return_if_fail (!GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lsrc))); v4lsrc->autoprobe_fps = g_value_get_boolean (value); break; case PROP_COPY_MODE: v4lsrc->copy_mode = g_value_get_boolean (value); break; case PROP_TIMESTAMP_OFFSET: v4lsrc->timestamp_offset = g_value_get_int64 (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/* this function is a bit of a last resort */ static void gst_v4lsrc_fixate (GstBaseSrc * bsrc, GstCaps * caps) { GstStructure *structure; int i; int targetwidth, targetheight; GstV4lSrc *v4lsrc = GST_V4LSRC (bsrc); struct video_capability *vcap = &GST_V4LELEMENT (v4lsrc)->vcap; struct video_window *vwin = &GST_V4LELEMENT (v4lsrc)->vwin; if (GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) { GST_DEBUG_OBJECT (v4lsrc, "device reported w: %d-%d, h: %d-%d", vcap->minwidth, vcap->maxwidth, vcap->minheight, vcap->maxheight); targetwidth = vcap->minwidth; targetheight = vcap->minheight; /* if we can get the current vwin settings, we use those to fixate */ if (!gst_v4l_get_capabilities (GST_V4LELEMENT (v4lsrc))) GST_DEBUG_OBJECT (v4lsrc, "failed getting capabilities"); else { targetwidth = vwin->width; targetheight = vwin->height; } } else { GST_DEBUG_OBJECT (v4lsrc, "device closed, guessing"); targetwidth = 320; targetheight = 200; } GST_DEBUG_OBJECT (v4lsrc, "targetting %dx%d", targetwidth, targetheight); for (i = 0; i < gst_caps_get_size (caps); ++i) { const GValue *v; structure = gst_caps_get_structure (caps, i); gst_structure_fixate_field_nearest_int (structure, "width", targetwidth); gst_structure_fixate_field_nearest_int (structure, "height", targetheight); gst_structure_fixate_field_nearest_fraction (structure, "framerate", 15, 2); v = gst_structure_get_value (structure, "format"); if (v && G_VALUE_TYPE (v) != GST_TYPE_FOURCC) { guint32 fourcc; g_return_if_fail (G_VALUE_TYPE (v) == GST_TYPE_LIST); fourcc = gst_value_get_fourcc (gst_value_list_get_value (v, 0)); gst_structure_set (structure, "format", GST_TYPE_FOURCC, fourcc, NULL); } } }
static GstBuffer * gst_v4lmjpegsink_buffer_new (GstBufferPool * pool, guint64 offset, guint size, gpointer user_data) { GstV4lMjpegSink *v4lmjpegsink = GST_V4LMJPEGSINK (user_data); GstBuffer *buffer = NULL; guint8 *data; gint num; if (!GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lmjpegsink))) return NULL; if (v4lmjpegsink->breq.size < size) { GST_DEBUG ("Requested buffer size is too large (%d > %ld)", size, v4lmjpegsink->breq.size); return NULL; } if (!gst_v4lmjpegsink_wait_frame (v4lmjpegsink, &num)) return NULL; data = gst_v4lmjpegsink_get_buffer (v4lmjpegsink, num); if (!data) return NULL; buffer = gst_buffer_new (); GST_BUFFER_DATA (buffer) = data; GST_BUFFER_MAXSIZE (buffer) = v4lmjpegsink->breq.size; GST_BUFFER_SIZE (buffer) = size; GST_BUFFER_POOL (buffer) = pool; GST_BUFFER_POOL_PRIVATE (buffer) = GINT_TO_POINTER (num); /* with this flag set, we don't need our own buffer_free() function */ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_DONTFREE); return buffer; }
static gboolean gst_v4lsrc_stop (GstBaseSrc * src) { GstV4lSrc *v4lsrc = GST_V4LSRC (src); if (GST_V4L_IS_ACTIVE (v4lsrc) && !gst_v4lsrc_capture_stop (v4lsrc)) return FALSE; if (GST_V4LELEMENT (v4lsrc)->buffer != NULL) { if (!gst_v4lsrc_capture_deinit (v4lsrc)) return FALSE; } if (!GST_BASE_SRC_CLASS (parent_class)->stop (src)) return FALSE; g_list_free (v4lsrc->colorspaces); v4lsrc->colorspaces = NULL; if (v4lsrc->fps_list) { g_value_unset (v4lsrc->fps_list); g_free (v4lsrc->fps_list); v4lsrc->fps_list = NULL; } return TRUE; }
static GstPadLinkReturn gst_v4lmjpegsink_sinkconnect (GstPad * pad, const GstCaps * vscapslist) { GstV4lMjpegSink *v4lmjpegsink; GstStructure *structure; v4lmjpegsink = GST_V4LMJPEGSINK (gst_pad_get_parent (pad)); /* in case the buffers are active (which means that we already * did capsnego before and didn't clean up), clean up anyways */ if (GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lmjpegsink))) if (!gst_v4lmjpegsink_playback_deinit (v4lmjpegsink)) return GST_PAD_LINK_REFUSED; structure = gst_caps_get_structure (vscapslist, 0); gst_structure_get_int (structure, "width", &v4lmjpegsink->width); gst_structure_get_int (structure, "height", &v4lmjpegsink->height); if (!gst_v4lmjpegsink_set_playback (v4lmjpegsink, v4lmjpegsink->width, v4lmjpegsink->height, v4lmjpegsink->x_offset, v4lmjpegsink->y_offset, GST_V4LELEMENT (v4lmjpegsink)->vchan.norm, 0)) /* TODO: interlacing */ return GST_PAD_LINK_REFUSED; /* set buffer info */ if (!gst_v4lmjpegsink_set_buffer (v4lmjpegsink, v4lmjpegsink->numbufs, v4lmjpegsink->bufsize)) return GST_PAD_LINK_REFUSED; if (!gst_v4lmjpegsink_playback_init (v4lmjpegsink)) return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_OK; }
static GstCaps * gst_v4ljpegsrc_getcaps (GstPad * pad) { GstCaps *list; GstV4lJpegSrc *v4ljpegsrc = GST_V4LJPEGSRC (gst_pad_get_parent (pad)); GstV4lSrc *v4lsrc = GST_V4LSRC (v4ljpegsrc); struct video_capability *vcap = &GST_V4LELEMENT (v4lsrc)->vcap; gfloat fps = 0.0; if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) { return gst_caps_new_any (); } if (!v4lsrc->autoprobe) { /* FIXME: query current caps and return those, with _any appended */ return gst_caps_new_any (); } list = gst_caps_new_simple ("image/jpeg", NULL); GST_DEBUG_OBJECT (v4ljpegsrc, "Device reports w: %d-%d, h: %d-%d, fps: %f", vcap->minwidth, vcap->maxwidth, vcap->minheight, vcap->maxheight, fps); if (vcap->minwidth < vcap->maxwidth) { gst_caps_set_simple (list, "width", GST_TYPE_INT_RANGE, vcap->minwidth, vcap->maxwidth, NULL); } else { gst_caps_set_simple (list, "width", G_TYPE_INT, vcap->minwidth, NULL); } if (vcap->minheight < vcap->maxheight) { gst_caps_set_simple (list, "height", GST_TYPE_INT_RANGE, vcap->minheight, vcap->maxheight, NULL); } else { gst_caps_set_simple (list, "height", G_TYPE_INT, vcap->minheight, NULL); } if (v4lsrc->fps_list) { GstStructure *structure = gst_caps_get_structure (list, 0); gst_structure_set_value (structure, "framerate", v4lsrc->fps_list); } GST_DEBUG_OBJECT (v4ljpegsrc, "caps: %" GST_PTR_FORMAT, list); return list; }
static void gst_v4l_xoverlay_set_window_handle (GstXOverlay * overlay, guintptr id) { XID xwindow_id = id; GstV4lElement *v4lelement = GST_V4LELEMENT (overlay); GstV4lXv *v4lxv; XWindowAttributes attr; gboolean change = (v4lelement->xwindow_id != xwindow_id); GST_LOG_OBJECT (v4lelement, "Changing port to %lx", xwindow_id); if (!v4lelement->xv && GST_V4L_IS_OPEN (v4lelement)) gst_v4l_xoverlay_open (v4lelement); v4lxv = v4lelement->xv; if (v4lxv) g_mutex_lock (v4lxv->mutex); if (change) { if (v4lelement->xwindow_id && v4lxv) { GST_DEBUG_OBJECT (v4lelement, "Disabling port %lx", v4lelement->xwindow_id); XvSelectPortNotify (v4lxv->dpy, v4lxv->port, 0); XvSelectVideoNotify (v4lxv->dpy, v4lelement->xwindow_id, 0); XvStopVideo (v4lxv->dpy, v4lxv->port, v4lelement->xwindow_id); } v4lelement->xwindow_id = xwindow_id; } if (!v4lxv || xwindow_id == 0) { if (v4lxv) g_mutex_unlock (v4lxv->mutex); return; } if (change) { GST_DEBUG_OBJECT (v4lelement, "Enabling port %lx", xwindow_id); /* draw */ XvSelectPortNotify (v4lxv->dpy, v4lxv->port, 1); XvSelectVideoNotify (v4lxv->dpy, v4lelement->xwindow_id, 1); } XGetWindowAttributes (v4lxv->dpy, v4lelement->xwindow_id, &attr); XvPutVideo (v4lxv->dpy, v4lxv->port, v4lelement->xwindow_id, DefaultGC (v4lxv->dpy, DefaultScreen (v4lxv->dpy)), 0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height); if (v4lxv->idle_id) g_source_remove (v4lxv->idle_id); v4lxv->idle_id = g_idle_add (idle_refresh, v4lelement); g_mutex_unlock (v4lxv->mutex); }
static void gst_v4l_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel) { GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel); gint norm; /* assert that we're opened and that we're using a known item */ g_return_if_fail (GST_V4L_IS_OPEN (v4lelement)); g_return_if_fail (gst_v4l_tuner_contains_channel (v4lelement, v4lchannel)); gst_v4l_get_chan_norm (v4lelement, NULL, &norm); gst_v4l_set_chan_norm (v4lelement, v4lchannel->index, norm); }
static void gst_v4l_tuner_set_norm (GstTuner * tuner, GstTunerNorm * norm) { GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); GstV4lTunerNorm *v4lnorm = GST_V4L_TUNER_NORM (norm); gint channel; /* assert that we're opened and that we're using a known item */ g_return_if_fail (GST_V4L_IS_OPEN (v4lelement)); g_return_if_fail (gst_v4l_tuner_contains_norm (v4lelement, v4lnorm)); gst_v4l_get_chan_norm (v4lelement, &channel, NULL); gst_v4l_set_chan_norm (v4lelement, channel, v4lnorm->index); }
static GstTunerNorm * gst_v4l_tuner_get_norm (GstTuner * tuner) { GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); GList *item; gint norm; /* assert that we're opened */ g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), NULL); gst_v4l_get_chan_norm (v4lelement, NULL, &norm); for (item = v4lelement->norms; item != NULL; item = item->next) { if (norm == GST_V4L_TUNER_NORM (item->data)->index) return GST_TUNER_NORM (item->data); } return NULL; }
static void gst_v4l_tuner_set_frequency (GstTuner * tuner, GstTunerChannel * channel, gulong frequency) { GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel); gint chan; /* assert that we're opened and that we're using a known item */ g_return_if_fail (GST_V4L_IS_OPEN (v4lelement)); g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)); g_return_if_fail (gst_v4l_tuner_contains_channel (v4lelement, v4lchannel)); gst_v4l_get_chan_norm (v4lelement, &chan, NULL); if (chan == GST_V4L_TUNER_CHANNEL (channel)->index) { gst_v4l_set_frequency (v4lelement, v4lchannel->tuner, frequency); } }
static GstTunerChannel * gst_v4l_tuner_get_channel (GstTuner * tuner) { GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); GList *item; gint channel; /* assert that we're opened */ g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), NULL); gst_v4l_get_chan_norm (v4lelement, &channel, NULL); for (item = v4lelement->channels; item != NULL; item = item->next) { if (channel == GST_V4L_TUNER_CHANNEL (item->data)->index) return GST_TUNER_CHANNEL (item->data); } return NULL; }
static gboolean idle_refresh (gpointer data) { GstV4lElement *v4lelement = GST_V4LELEMENT (data); GstV4lXv *v4lxv = v4lelement->xv; XWindowAttributes attr; if (v4lxv) { g_mutex_lock (v4lxv->mutex); XGetWindowAttributes (v4lxv->dpy, v4lelement->xwindow_id, &attr); XvPutVideo (v4lxv->dpy, v4lxv->port, v4lelement->xwindow_id, DefaultGC (v4lxv->dpy, DefaultScreen (v4lxv->dpy)), 0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height); v4lxv->idle_id = 0; g_mutex_unlock (v4lxv->mutex); } /* once */ return FALSE; }
static gint gst_v4l_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel) { GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel); gint chan; guint signal = 0; /* assert that we're opened and that we're using a known item */ g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), 0); g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY), 0); g_return_val_if_fail (gst_v4l_tuner_contains_channel (v4lelement, v4lchannel), 0); gst_v4l_get_chan_norm (v4lelement, &chan, NULL); if (chan == GST_V4L_TUNER_CHANNEL (channel)->index && GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { gst_v4l_get_signal (v4lelement, v4lchannel->tuner, &signal); } return (gint) signal; }
static GstPadLinkReturn gst_v4ljpegsrc_src_link (GstPad * pad, const GstCaps * vscapslist) { GstV4lJpegSrc *v4ljpegsrc; GstV4lSrc *v4lsrc; gint w, h, palette = -1; const GValue *fps; GstStructure *structure; gboolean was_capturing; struct video_window *vwin; v4ljpegsrc = GST_V4LJPEGSRC (gst_pad_get_parent (pad)); v4lsrc = GST_V4LSRC (v4ljpegsrc); vwin = &GST_V4LELEMENT (v4lsrc)->vwin; was_capturing = v4lsrc->is_capturing; /* in case the buffers are active (which means that we already * did capsnego before and didn't clean up), clean up anyways */ if (GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lsrc))) { if (was_capturing) { if (!gst_v4lsrc_capture_stop (v4lsrc)) return GST_PAD_LINK_REFUSED; } if (!gst_v4lsrc_capture_deinit (v4lsrc)) return GST_PAD_LINK_REFUSED; } else if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) { return GST_PAD_LINK_DELAYED; } structure = gst_caps_get_structure (vscapslist, 0); gst_structure_get_int (structure, "width", &w); gst_structure_get_int (structure, "height", &h); fps = gst_structure_get_value (structure, "framerate"); GST_DEBUG_OBJECT (v4ljpegsrc, "linking with %dx%d at %d/%d fps", w, h, gst_value_get_fraction_numerator (fps), gst_value_get_fraction_denominator (fps)); /* set framerate if it's not already correct */ if (fps != gst_v4lsrc_get_fps (v4lsrc)) { int fps_index = fps / 15.0 * 16; GST_DEBUG_OBJECT (v4ljpegsrc, "Trying to set fps index %d", fps_index); /* set bits 16 to 21 to 0 */ vwin->flags &= (0x3F00 - 1); /* set bits 16 to 21 to the index */ vwin->flags |= fps_index << 16; if (!gst_v4l_set_window_properties (GST_V4LELEMENT (v4lsrc))) { return GST_PAD_LINK_DELAYED; } } /* * Try to set the camera to capture RGB24 */ palette = VIDEO_PALETTE_RGB24; v4lsrc->buffer_size = w * h * 3; GST_DEBUG_OBJECT (v4ljpegsrc, "trying to set_capture %dx%d, palette %d", w, h, palette); /* this only fills in v4lsrc->mmap values */ if (!gst_v4lsrc_set_capture (v4lsrc, w, h, palette)) { GST_WARNING_OBJECT (v4ljpegsrc, "could not set_capture %dx%d, palette %d", w, h, palette); return GST_PAD_LINK_REFUSED; } /* first try the negotiated settings using try_capture */ if (!gst_v4lsrc_try_capture (v4lsrc, w, h, palette)) { GST_DEBUG_OBJECT (v4ljpegsrc, "failed trying palette %d for %dx%d", palette, w, h); return GST_PAD_LINK_REFUSED; } if (!gst_v4lsrc_capture_init (v4lsrc)) return GST_PAD_LINK_REFUSED; if (was_capturing || GST_STATE (v4lsrc) == GST_STATE_PLAYING) { if (!gst_v4lsrc_capture_start (v4lsrc)) return GST_PAD_LINK_REFUSED; } return GST_PAD_LINK_OK; }
static GstCaps * gst_v4lsrc_get_caps (GstBaseSrc * src) { GstCaps *list; GstV4lSrc *v4lsrc = GST_V4LSRC (src); struct video_capability *vcap = &GST_V4LELEMENT (v4lsrc)->vcap; gint width = GST_V4LELEMENT (src)->vcap.minwidth; gint height = GST_V4LELEMENT (src)->vcap.minheight; gint i; gint fps_n, fps_d; GList *item; if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) { return gst_v4lsrc_get_any_caps (); } if (!v4lsrc->autoprobe) { /* FIXME: query current caps and return those, with _any appended */ return gst_v4lsrc_get_any_caps (); } if (!v4lsrc->colorspaces) { GST_DEBUG_OBJECT (v4lsrc, "Checking supported palettes"); for (i = 0; all_palettes[i] != -1; i++) { /* try palette out */ if (!gst_v4lsrc_try_capture (v4lsrc, width, height, all_palettes[i])) continue; GST_DEBUG_OBJECT (v4lsrc, "Added palette %d (%s) to supported list", all_palettes[i], gst_v4lsrc_palette_name (all_palettes[i])); v4lsrc->colorspaces = g_list_append (v4lsrc->colorspaces, GINT_TO_POINTER (all_palettes[i])); } GST_DEBUG_OBJECT (v4lsrc, "%d palette(s) supported", g_list_length (v4lsrc->colorspaces)); if (v4lsrc->autoprobe_fps) { GST_DEBUG_OBJECT (v4lsrc, "autoprobing framerates"); v4lsrc->fps_list = gst_v4lsrc_get_fps_list (v4lsrc); } } if (!gst_v4lsrc_get_fps (v4lsrc, &fps_n, &fps_d)) { fps_n = 0; fps_d = 1; } list = gst_caps_new_empty (); for (item = v4lsrc->colorspaces; item != NULL; item = item->next) { GstCaps *one; one = gst_v4lsrc_palette_to_caps (GPOINTER_TO_INT (item->data)); if (!one) { GST_WARNING_OBJECT (v4lsrc, "Palette %d gave no caps\n", GPOINTER_TO_INT (item->data)); continue; } GST_DEBUG_OBJECT (v4lsrc, "Device reports w: %d-%d, h: %d-%d, fps: %d/%d for palette %d", vcap->minwidth, vcap->maxwidth, vcap->minheight, vcap->maxheight, fps_n, fps_d, GPOINTER_TO_INT (item->data)); if (vcap->minwidth < vcap->maxwidth) { gst_caps_set_simple (one, "width", GST_TYPE_INT_RANGE, vcap->minwidth, vcap->maxwidth, NULL); } else { gst_caps_set_simple (one, "width", G_TYPE_INT, vcap->minwidth, NULL); } if (vcap->minheight < vcap->maxheight) { gst_caps_set_simple (one, "height", GST_TYPE_INT_RANGE, vcap->minheight, vcap->maxheight, NULL); } else { gst_caps_set_simple (one, "height", G_TYPE_INT, vcap->minheight, NULL); } if (v4lsrc->autoprobe_fps) { GstStructure *structure = gst_caps_get_structure (one, 0); if (v4lsrc->fps_list) { gst_structure_set_value (structure, "framerate", v4lsrc->fps_list); } else { gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); } } else { gst_caps_set_simple (one, "framerate", GST_TYPE_FRACTION_RANGE, 1, 1, 100, 1, NULL); } GST_DEBUG_OBJECT (v4lsrc, "caps: %" GST_PTR_FORMAT, one); gst_caps_append (list, one); } return list; }
static const GList * gst_v4l_tuner_list_channels (GstTuner * tuner) { return GST_V4LELEMENT (tuner)->channels; }
static gboolean gst_v4lsrc_set_caps (GstBaseSrc * src, GstCaps * caps) { GstV4lSrc *v4lsrc; guint32 fourcc; gint bpp, depth, w, h, palette = -1; const GValue *new_fps; gint cur_fps_n, cur_fps_d; GstStructure *structure; struct video_window *vwin; v4lsrc = GST_V4LSRC (src); vwin = &GST_V4LELEMENT (v4lsrc)->vwin; /* if we're not open, punt -- we'll get setcaps'd later via negotiate */ if (!GST_V4L_IS_OPEN (v4lsrc)) return FALSE; /* make sure we stop capturing and dealloc buffers */ if (GST_V4L_IS_ACTIVE (v4lsrc)) { if (!gst_v4lsrc_capture_stop (v4lsrc)) return FALSE; if (!gst_v4lsrc_capture_deinit (v4lsrc)) return FALSE; } /* it's fixed, one struct */ structure = gst_caps_get_structure (caps, 0); if (strcmp (gst_structure_get_name (structure), "video/x-raw-yuv") == 0) gst_structure_get_fourcc (structure, "format", &fourcc); else fourcc = GST_MAKE_FOURCC ('R', 'G', 'B', ' '); gst_structure_get_int (structure, "width", &w); gst_structure_get_int (structure, "height", &h); new_fps = gst_structure_get_value (structure, "framerate"); /* set framerate if it's not already correct */ if (!gst_v4lsrc_get_fps (v4lsrc, &cur_fps_n, &cur_fps_d)) return FALSE; if (new_fps) { GST_DEBUG_OBJECT (v4lsrc, "linking with %dx%d at %d/%d fps", w, h, gst_value_get_fraction_numerator (new_fps), gst_value_get_fraction_denominator (new_fps)); if (gst_value_get_fraction_numerator (new_fps) != cur_fps_n || gst_value_get_fraction_denominator (new_fps) != cur_fps_d) { int fps_index = (gst_value_get_fraction_numerator (new_fps) * 16) / (gst_value_get_fraction_denominator (new_fps) * 15); GST_DEBUG_OBJECT (v4lsrc, "Trying to set fps index %d", fps_index); /* set bits 16 to 21 to 0 */ vwin->flags &= (0x3F00 - 1); /* set bits 16 to 21 to the index */ vwin->flags |= fps_index << 16; if (!gst_v4l_set_window_properties (GST_V4LELEMENT (v4lsrc))) { return FALSE; } } } switch (fourcc) { case GST_MAKE_FOURCC ('I', '4', '2', '0'): palette = VIDEO_PALETTE_YUV420P; v4lsrc->buffer_size = ((w + 1) & ~1) * ((h + 1) & ~1) * 1.5; break; case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): palette = VIDEO_PALETTE_YUV422; v4lsrc->buffer_size = ((w + 1) & ~1) * h * 2; break; case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): palette = VIDEO_PALETTE_UYVY; v4lsrc->buffer_size = ((w + 1) & ~1) * h * 2; break; case GST_MAKE_FOURCC ('Y', '4', '1', 'B'): palette = VIDEO_PALETTE_YUV411P; v4lsrc->buffer_size = ((w + 3) & ~3) * h * 1.5; break; case GST_MAKE_FOURCC ('Y', '4', '1', 'P'): palette = VIDEO_PALETTE_YUV411; v4lsrc->buffer_size = ((w + 3) & ~3) * h * 1.5; break; case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'): palette = VIDEO_PALETTE_YUV410P; v4lsrc->buffer_size = ((w + 3) & ~3) * ((h + 3) & ~3) * 1.125; break; case GST_MAKE_FOURCC ('Y', '4', '2', 'B'): palette = VIDEO_PALETTE_YUV422P; v4lsrc->buffer_size = ((w + 1) & ~1) * h * 2; break; case GST_MAKE_FOURCC ('R', 'G', 'B', ' '): gst_structure_get_int (structure, "depth", &depth); switch (depth) { case 15: palette = VIDEO_PALETTE_RGB555; v4lsrc->buffer_size = w * h * 2; break; case 16: palette = VIDEO_PALETTE_RGB565; v4lsrc->buffer_size = w * h * 2; break; case 24: gst_structure_get_int (structure, "bpp", &bpp); switch (bpp) { case 24: palette = VIDEO_PALETTE_RGB24; v4lsrc->buffer_size = w * h * 3; break; case 32: palette = VIDEO_PALETTE_RGB32; v4lsrc->buffer_size = w * h * 4; break; default: break; } break; default: break; } break; default: break; } if (palette == -1) { GST_WARNING_OBJECT (v4lsrc, "palette for fourcc %" GST_FOURCC_FORMAT " is -1, refusing link", GST_FOURCC_ARGS (fourcc)); return FALSE; } GST_DEBUG_OBJECT (v4lsrc, "trying to set_capture %dx%d, palette %d", w, h, palette); /* this only fills in v4lsrc->mmap values */ if (!gst_v4lsrc_set_capture (v4lsrc, w, h, palette)) { GST_WARNING_OBJECT (v4lsrc, "could not set_capture %dx%d, palette %d", w, h, palette); return FALSE; } /* first try the negotiated settings using try_capture */ if (!gst_v4lsrc_try_capture (v4lsrc, w, h, palette)) { GST_DEBUG_OBJECT (v4lsrc, "failed trying palette %d for %dx%d", palette, w, h); return FALSE; } if (!gst_v4lsrc_capture_init (v4lsrc)) return FALSE; if (!gst_v4lsrc_capture_start (v4lsrc)) return FALSE; return TRUE; }
static const GList * gst_v4l_tuner_list_norms (GstTuner * tuner) { return GST_V4LELEMENT (tuner)->norms; }