void empathy_video_src_set_channel (GstElement *src, EmpathyGstVideoSrcChannel channel, guint percent) { GstElement *color; GstColorBalance *balance; const GList *channels; GList *l; /* Find something supporting GstColorBalance */ color = gst_bin_get_by_interface (GST_BIN (src), GST_TYPE_COLOR_BALANCE); if (color == NULL) return; balance = GST_COLOR_BALANCE (color); channels = gst_color_balance_list_channels (balance); for (l = (GList *) channels; l != NULL; l = g_list_next (l)) { GstColorBalanceChannel *c = GST_COLOR_BALANCE_CHANNEL (l->data); if (g_ascii_strcasecmp (c->label, channel_names[channel]) == 0) { gst_color_balance_set_value (balance, c, ((c->max_value - c->min_value) * percent)/100 + c->min_value); break; } } g_object_unref (color); }
guint empathy_video_src_get_supported_channels (GstElement *src) { GstColorBalance *balance; const GList *channels; GList *l; guint result = 0; balance = dup_color_balance (src); if (balance == NULL) goto out; channels = gst_color_balance_list_channels (balance); for (l = (GList *) channels; l != NULL; l = g_list_next (l)) { GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (l->data); int i; for (i = 0; i < NR_EMPATHY_GST_VIDEO_SRC_CHANNELS; i++) { if (g_ascii_strcasecmp (channel->label, channel_names[i]) == 0) { result |= (1 << i); break; } } } g_object_unref (balance); out: return result; }
guint empathy_video_src_get_channel (GstElement *src, EmpathyGstVideoSrcChannel channel) { GstColorBalance *balance; const GList *channels; GList *l; guint percent = 0; balance = dup_color_balance (src); if (balance == NULL) return percent; channels = gst_color_balance_list_channels (balance); for (l = (GList *) channels; l != NULL; l = g_list_next (l)) { GstColorBalanceChannel *c = GST_COLOR_BALANCE_CHANNEL (l->data); if (g_ascii_strcasecmp (c->label, channel_names[channel]) == 0) { percent = ((gst_color_balance_get_value (balance, c) - c->min_value) * 100) / (c->max_value - c->min_value); break; } } g_object_unref (balance); return percent; }
QList<ColorBalanceChannelPtr> ColorBalance::channels() const { QList<ColorBalanceChannelPtr> result; const GList *list = gst_color_balance_list_channels(object<GstColorBalance>()); while(list) { result.append(ColorBalanceChannelPtr::wrap(GST_COLOR_BALANCE_CHANNEL(list->data))); list = list->next; } return result; }
static void gst_color_balance_channel_dispose (GObject * object) { GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object); if (channel->label) g_free (channel->label); channel->label = NULL; if (parent_class->dispose) parent_class->dispose (object); }
static void gst_qt_quick2_video_sink_finalize (GObject *gobject) { GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (gobject); delete self->priv->delegate; self->priv->delegate = 0; while (self->priv->channels_list) { GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL(self->priv->channels_list->data); g_object_unref(channel); self->priv->channels_list = g_list_next(self->priv->channels_list); } g_list_free(self->priv->channels_list); G_OBJECT_CLASS (parent_class)->finalize (gobject); }
static void gst_qt_quick2_video_sink_init (GstQtQuick2VideoSink *self) { self->priv = GST_QT_QUICK2_VIDEO_SINK_GET_PRIVATE (self); // delegate self->priv->delegate = new QtQuick2VideoSinkDelegate(GST_ELEMENT(self)); // colorbalance GstColorBalanceChannel *channel; self->priv->channels_list = NULL; for (int i=0; i < LABEL_LAST; i++) { channel = GST_COLOR_BALANCE_CHANNEL(g_object_new(GST_TYPE_COLOR_BALANCE_CHANNEL, NULL)); channel->label = g_strdup(s_colorbalance_labels[i]); channel->min_value = -100; channel->max_value = 100; self->priv->channels_list = g_list_append(self->priv->channels_list, channel); } }
/****************************************************** * gst_v4l2_empty_lists() and gst_v4l2_fill_lists(): * fill/empty the lists of enumerations * return value: TRUE on success, FALSE on error ******************************************************/ static gboolean gst_v4l2_fill_lists (GstV4l2Object * v4l2object) { gint n; GstElement *e; e = v4l2object->element; GST_DEBUG_OBJECT (e, "getting enumerations"); GST_V4L2_CHECK_OPEN (v4l2object); GST_DEBUG_OBJECT (e, " channels"); /* and now, the channels */ for (n = 0;; n++) { struct v4l2_input input; GstV4l2TunerChannel *v4l2channel; GstTunerChannel *channel; memset (&input, 0, sizeof (input)); input.index = n; if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_ENUMINPUT, &input) < 0) { if (errno == EINVAL) break; /* end of enumeration */ else { GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, (_("Failed to query attributes of input %d in device %s"), n, v4l2object->videodev), ("Failed to get %d in input enumeration for %s. (%d - %s)", n, v4l2object->videodev, errno, strerror (errno))); return FALSE; } } GST_LOG_OBJECT (e, " index: %d", input.index); GST_LOG_OBJECT (e, " name: '%s'", input.name); GST_LOG_OBJECT (e, " type: %08x", input.type); GST_LOG_OBJECT (e, " audioset: %08x", input.audioset); GST_LOG_OBJECT (e, " std: %016x", (guint) input.std); GST_LOG_OBJECT (e, " status: %08x", input.status); v4l2channel = g_object_new (GST_TYPE_V4L2_TUNER_CHANNEL, NULL); channel = GST_TUNER_CHANNEL (v4l2channel); channel->label = g_strdup ((const gchar *) input.name); channel->flags = GST_TUNER_CHANNEL_INPUT; v4l2channel->index = n; if (input.type == V4L2_INPUT_TYPE_TUNER) { struct v4l2_tuner vtun; v4l2channel->tuner = input.tuner; channel->flags |= GST_TUNER_CHANNEL_FREQUENCY; vtun.index = input.tuner; if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun) < 0) { GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, (_("Failed to get setting of tuner %d on device '%s'."), input.tuner, v4l2object->videodev), GST_ERROR_SYSTEM); g_object_unref (G_OBJECT (channel)); return FALSE; } channel->freq_multiplicator = 62.5 * ((vtun.capability & V4L2_TUNER_CAP_LOW) ? 1 : 1000); channel->min_frequency = vtun.rangelow * channel->freq_multiplicator; channel->max_frequency = vtun.rangehigh * channel->freq_multiplicator; channel->min_signal = 0; channel->max_signal = 0xffff; } if (input.audioset) { /* we take the first. We don't care for * the others for now */ while (!(input.audioset & (1 << v4l2channel->audio))) v4l2channel->audio++; channel->flags |= GST_TUNER_CHANNEL_AUDIO; } v4l2object->channels = g_list_prepend (v4l2object->channels, (gpointer) channel); } v4l2object->channels = g_list_reverse (v4l2object->channels); GST_DEBUG_OBJECT (e, " norms"); /* norms... */ for (n = 0;; n++) { struct v4l2_standard standard = { 0, }; GstV4l2TunerNorm *v4l2norm; GstTunerNorm *norm; /* fill in defaults */ standard.frameperiod.numerator = 1; standard.frameperiod.denominator = 0; standard.index = n; if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_ENUMSTD, &standard) < 0) { if (errno == EINVAL || errno == ENOTTY) break; /* end of enumeration */ else { GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, (_("Failed to query norm on device '%s'."), v4l2object->videodev), ("Failed to get attributes for norm %d on devide '%s'. (%d - %s)", n, v4l2object->videodev, errno, strerror (errno))); return FALSE; } } GST_DEBUG_OBJECT (e, " '%s', fps: %d / %d", standard.name, standard.frameperiod.denominator, standard.frameperiod.numerator); v4l2norm = g_object_new (GST_TYPE_V4L2_TUNER_NORM, NULL); norm = GST_TUNER_NORM (v4l2norm); norm->label = g_strdup ((const gchar *) standard.name); gst_value_set_fraction (&norm->framerate, standard.frameperiod.denominator, standard.frameperiod.numerator); v4l2norm->index = standard.id; v4l2object->norms = g_list_prepend (v4l2object->norms, (gpointer) norm); } v4l2object->norms = g_list_reverse (v4l2object->norms); GST_DEBUG_OBJECT (e, " controls+menus"); /* and lastly, controls+menus (if appropriate) */ for (n = V4L2_CID_BASE;; n++) { struct v4l2_queryctrl control = { 0, }; GstV4l2ColorBalanceChannel *v4l2channel; GstColorBalanceChannel *channel; /* when we reached the last official CID, continue with private CIDs */ if (n == V4L2_CID_LASTP1) { GST_DEBUG_OBJECT (e, "checking private CIDs"); n = V4L2_CID_PRIVATE_BASE; } GST_DEBUG_OBJECT (e, "checking control %08x", n); control.id = n; if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL, &control) < 0) { if (errno == EINVAL) { if (n < V4L2_CID_PRIVATE_BASE) { GST_DEBUG_OBJECT (e, "skipping control %08x", n); /* continue so that we also check private controls */ continue; } else { GST_DEBUG_OBJECT (e, "controls finished"); break; } } else { GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, (_("Failed getting controls attributes on device '%s'."), v4l2object->videodev), ("Failed querying control %d on device '%s'. (%d - %s)", n, v4l2object->videodev, errno, strerror (errno))); return FALSE; } } if (control.flags & V4L2_CTRL_FLAG_DISABLED) { GST_DEBUG_OBJECT (e, "skipping disabled control"); continue; } switch (n) { 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: #ifdef V4L2_CID_SHARPNESS case V4L2_CID_SHARPNESS: #endif /* we only handle these for now (why?) */ break; case V4L2_CID_HFLIP: case V4L2_CID_VFLIP: case V4L2_CID_HCENTER: case V4L2_CID_VCENTER: #ifdef V4L2_CID_PAN_RESET case V4L2_CID_PAN_RESET: #endif #ifdef V4L2_CID_TILT_RESET case V4L2_CID_TILT_RESET: #endif /* not handled here, handled by VideoOrientation interface */ control.id++; break; 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: /* FIXME: We should implement GstMixer interface */ /* fall through */ default: GST_DEBUG_OBJECT (e, "ControlID %s (%x) unhandled, FIXME", control.name, n); control.id++; break; } if (n != control.id) continue; GST_DEBUG_OBJECT (e, "Adding ControlID %s (%x)", control.name, n); v4l2channel = g_object_new (GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL, NULL); channel = GST_COLOR_BALANCE_CHANNEL (v4l2channel); channel->label = g_strdup ((const gchar *) control.name); v4l2channel->id = n; #if 0 /* FIXME: it will be need just when handling private controls *(currently none of base controls are of this type) */ if (control.type == V4L2_CTRL_TYPE_MENU) { struct v4l2_querymenu menu, *mptr; int i; menu.id = n; for (i = 0;; i++) { menu.index = i; if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYMENU, &menu) < 0) { if (errno == EINVAL) break; /* end of enumeration */ else { GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, (_("Failed getting controls attributes on device '%s'."), v4l2object->videodev), ("Failed to get %d in menu enumeration for %s. (%d - %s)", n, v4l2object->videodev, errno, strerror (errno))); return FALSE; } } mptr = g_malloc (sizeof (menu)); memcpy (mptr, &menu, sizeof (menu)); menus = g_list_append (menus, mptr); } } v4l2object->menus = g_list_append (v4l2object->menus, menus); #endif switch (control.type) { case V4L2_CTRL_TYPE_INTEGER: channel->min_value = control.minimum; channel->max_value = control.maximum; break; case V4L2_CTRL_TYPE_BOOLEAN: channel->min_value = FALSE; channel->max_value = TRUE; break; default: /* FIXME we should find out how to handle V4L2_CTRL_TYPE_BUTTON. BUTTON controls like V4L2_CID_DO_WHITE_BALANCE can just be set (1) or unset (0), but can't be queried */ GST_DEBUG_OBJECT (e, "Control with non supported type %s (%x), type=%d", control.name, n, control.type); channel->min_value = channel->max_value = 0; break; } v4l2object->colors = g_list_prepend (v4l2object->colors, (gpointer) channel); } v4l2object->colors = g_list_reverse (v4l2object->colors); GST_DEBUG_OBJECT (e, "done"); return TRUE; }