static gboolean gst_frei0r_mixer_set_caps (GstFrei0rMixer * self, GstPad * pad, GstCaps * caps) { gboolean ret = TRUE; if (!self->caps) { gst_caps_replace (&self->caps, caps); ret = gst_pad_set_caps (self->src, caps); if (ret) { GstVideoInfo info; gst_video_info_init (&info); if (!gst_video_info_from_caps (&self->info, caps)) { ret = FALSE; } } } else if (!gst_caps_is_equal (caps, self->caps)) { if (gst_pad_peer_query_accept_caps (pad, self->caps)) gst_pad_push_event (pad, gst_event_new_reconfigure ()); ret = FALSE; } return ret; }
/* the first caps we receive on any of the sinkpads will define the caps for all * the other sinkpads because we can only mix streams with the same caps. */ static gboolean gst_adder_setcaps (GstAdder * adder, GstPad * pad, GstCaps * orig_caps) { GstCaps *caps; GstAudioInfo info; GstStructure *s; gint channels; caps = gst_caps_copy (orig_caps); s = gst_caps_get_structure (caps, 0); if (gst_structure_get_int (s, "channels", &channels)) if (channels <= 2) gst_structure_remove_field (s, "channel-mask"); if (!gst_audio_info_from_caps (&info, caps)) goto invalid_format; GST_OBJECT_LOCK (adder); /* don't allow reconfiguration for now; there's still a race between the * different upstream threads doing query_caps + accept_caps + sending * (possibly different) CAPS events, but there's not much we can do about * that, upstream needs to deal with it. */ if (adder->current_caps != NULL) { if (gst_audio_info_is_equal (&info, &adder->info)) { GST_OBJECT_UNLOCK (adder); gst_caps_unref (caps); return TRUE; } else { GST_DEBUG_OBJECT (pad, "got input caps %" GST_PTR_FORMAT ", but " "current caps are %" GST_PTR_FORMAT, caps, adder->current_caps); GST_OBJECT_UNLOCK (adder); gst_pad_push_event (pad, gst_event_new_reconfigure ()); gst_caps_unref (caps); return FALSE; } } GST_INFO_OBJECT (pad, "setting caps to %" GST_PTR_FORMAT, caps); adder->current_caps = gst_caps_ref (caps); memcpy (&adder->info, &info, sizeof (info)); GST_OBJECT_UNLOCK (adder); /* send caps event later, after stream-start event */ GST_INFO_OBJECT (pad, "handle caps change to %" GST_PTR_FORMAT, caps); gst_caps_unref (caps); return TRUE; /* ERRORS */ invalid_format: { gst_caps_unref (caps); GST_WARNING_OBJECT (adder, "invalid format set as caps"); return FALSE; } }
static gboolean start_image_capture (GstWrapperCameraBinSrc * self) { GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self); GstPhotography *photography = (GstPhotography *) gst_bin_get_by_interface (GST_BIN_CAST (bcamsrc), GST_TYPE_PHOTOGRAPHY); gboolean ret = FALSE; GstCaps *caps; GST_DEBUG_OBJECT (self, "Starting image capture"); gst_element_set_state (self->src_vid_src, GST_STATE_READY); if (self->image_renegotiate) { /* clean capsfilter caps so they don't interfere here */ g_object_set (self->src_filter, "caps", NULL, NULL); if (self->src_zoom_filter) g_object_set (self->src_zoom_filter, "caps", NULL, NULL); caps = gst_pad_get_allowed_caps (self->imgsrc); gst_caps_replace (&self->image_capture_caps, caps); gst_caps_unref (caps); /* FIXME - do we need to update basecamerasrc width/height somehow here? * if not, i think we need to do something about _when_ they get updated * to be sure that set_element_zoom doesn't use the wrong values */ /* We caught this event in the src pad event handler and now we want to * actually push it upstream */ gst_pad_send_event (self->outsel_imgpad, gst_event_new_reconfigure ()); self->image_renegotiate = FALSE; } if (photography) { gst_element_set_state (self->src_vid_src, GST_STATE_PLAYING); GST_DEBUG_OBJECT (self, "prepare image capture caps %" GST_PTR_FORMAT, self->image_capture_caps); ret = gst_photography_prepare_for_capture (photography, (GstPhotographyCapturePrepared) img_capture_prepared, self->image_capture_caps, self); } else { g_mutex_unlock (&bcamsrc->capturing_mutex); gst_wrapper_camera_bin_reset_video_src_caps (self, self->image_capture_caps); g_mutex_lock (&bcamsrc->capturing_mutex); ret = TRUE; gst_element_set_state (self->src_vid_src, GST_STATE_PLAYING); } return ret; }
static void gst_valve_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstValve *valve = GST_VALVE (object); switch (prop_id) { case PROP_DROP: g_atomic_int_set (&valve->drop, g_value_get_boolean (value)); gst_pad_push_event (valve->sinkpad, gst_event_new_reconfigure ()); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void _size_changed_cb (GtkWidget * widget, GdkRectangle * rectangle, GstGtkGLSink * gtk_sink) { gint scale_factor, width, height; gboolean reconfigure; scale_factor = gtk_widget_get_scale_factor (widget); width = scale_factor * gtk_widget_get_allocated_width (widget); height = scale_factor * gtk_widget_get_allocated_height (widget); GST_OBJECT_LOCK (gtk_sink); reconfigure = (width != gtk_sink->display_width || height != gtk_sink->display_height); gtk_sink->display_width = width; gtk_sink->display_height = height; GST_OBJECT_UNLOCK (gtk_sink); if (reconfigure) { GST_DEBUG_OBJECT (gtk_sink, "Sending reconfigure event on sinkpad."); gst_pad_push_event (GST_BASE_SINK (gtk_sink)->sinkpad, gst_event_new_reconfigure ()); } }
/* the first caps we receive on any of the sinkpads will define the caps for all * the other sinkpads because we can only mix streams with the same caps. */ static gboolean gst_audiomixer_setcaps (GstAudioMixer * audiomixer, GstPad * pad, GstCaps * orig_caps) { GstAggregator *agg = GST_AGGREGATOR (audiomixer); GstAudioAggregator *aagg = GST_AUDIO_AGGREGATOR (audiomixer); GstCaps *caps; GstAudioInfo info; GstStructure *s; gint channels = 0; caps = gst_caps_copy (orig_caps); s = gst_caps_get_structure (caps, 0); if (gst_structure_get_int (s, "channels", &channels)) if (channels <= 2) gst_structure_remove_field (s, "channel-mask"); if (!gst_audio_info_from_caps (&info, caps)) goto invalid_format; if (channels == 1) { GstCaps *filter; GstCaps *downstream_caps; if (audiomixer->filter_caps) filter = gst_caps_intersect_full (caps, audiomixer->filter_caps, GST_CAPS_INTERSECT_FIRST); else filter = gst_caps_ref (caps); downstream_caps = gst_pad_peer_query_caps (agg->srcpad, filter); gst_caps_unref (filter); if (downstream_caps) { gst_caps_unref (caps); caps = downstream_caps; if (gst_caps_is_empty (caps)) { gst_caps_unref (caps); return FALSE; } caps = gst_caps_fixate (caps); } } GST_OBJECT_LOCK (audiomixer); /* don't allow reconfiguration for now; there's still a race between the * different upstream threads doing query_caps + accept_caps + sending * (possibly different) CAPS events, but there's not much we can do about * that, upstream needs to deal with it. */ if (aagg->current_caps != NULL) { if (gst_audio_info_is_equal (&info, &aagg->info)) { GST_OBJECT_UNLOCK (audiomixer); gst_caps_unref (caps); gst_audio_aggregator_set_sink_caps (aagg, GST_AUDIO_AGGREGATOR_PAD (pad), orig_caps); return TRUE; } else { GST_DEBUG_OBJECT (pad, "got input caps %" GST_PTR_FORMAT ", but " "current caps are %" GST_PTR_FORMAT, caps, aagg->current_caps); GST_OBJECT_UNLOCK (audiomixer); gst_pad_push_event (pad, gst_event_new_reconfigure ()); gst_caps_unref (caps); return FALSE; } } else { gst_caps_replace (&aagg->current_caps, caps); aagg->info = info; gst_pad_mark_reconfigure (GST_AGGREGATOR_SRC_PAD (agg)); } GST_OBJECT_UNLOCK (audiomixer); gst_audio_aggregator_set_sink_caps (aagg, GST_AUDIO_AGGREGATOR_PAD (pad), orig_caps); GST_INFO_OBJECT (pad, "handle caps change to %" GST_PTR_FORMAT, caps); gst_caps_unref (caps); return TRUE; /* ERRORS */ invalid_format: { gst_caps_unref (caps); GST_WARNING_OBJECT (audiomixer, "invalid format set as caps"); return FALSE; } }
static gboolean start_image_capture (GstWrapperCameraBinSrc * self) { GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self); GstPhotography *photography = (GstPhotography *) gst_bin_get_by_interface (GST_BIN_CAST (bcamsrc), GST_TYPE_PHOTOGRAPHY); gboolean ret = FALSE; GstCaps *caps; GstPad *pad, *peer; GST_DEBUG_OBJECT (self, "Starting image capture"); gst_element_set_state (self->src_vid_src, GST_STATE_READY); /* FIXME - V4L2 source will not close the device until all buffers have came * back. Flushing the pipeline, will ensure it's properly closed, and that * setting it back to PLAYING will work. This is more a workaround then a * solution to buffer reclaiming. */ pad = gst_element_get_static_pad (self->src_vid_src, "src"); peer = gst_pad_get_peer (pad); gst_object_unref (pad); gst_pad_send_event (peer, gst_event_new_flush_start ()); gst_pad_send_event (peer, gst_event_new_flush_stop (TRUE)); gst_object_unref (peer); if (self->image_renegotiate) { /* clean capsfilter caps so they don't interfere here */ g_object_set (self->src_filter, "caps", NULL, NULL); if (self->src_zoom_filter) g_object_set (self->src_zoom_filter, "caps", NULL, NULL); caps = gst_pad_get_allowed_caps (self->imgsrc); gst_caps_replace (&self->image_capture_caps, caps); gst_caps_unref (caps); /* FIXME - do we need to update basecamerasrc width/height somehow here? * if not, i think we need to do something about _when_ they get updated * to be sure that set_element_zoom doesn't use the wrong values */ /* We caught this event in the src pad event handler and now we want to * actually push it upstream */ gst_pad_send_event (self->outsel_imgpad, gst_event_new_reconfigure ()); self->image_renegotiate = FALSE; } if (photography) { gst_element_set_state (self->src_vid_src, GST_STATE_PLAYING); GST_DEBUG_OBJECT (self, "prepare image capture caps %" GST_PTR_FORMAT, self->image_capture_caps); ret = gst_photography_prepare_for_capture (photography, (GstPhotographyCapturePrepared) img_capture_prepared, self->image_capture_caps, self); } else { g_mutex_unlock (&bcamsrc->capturing_mutex); gst_wrapper_camera_bin_reset_video_src_caps (self, self->image_capture_caps); g_mutex_lock (&bcamsrc->capturing_mutex); ret = TRUE; gst_element_set_state (self->src_vid_src, GST_STATE_PLAYING); } return ret; }