static gboolean gst_gl_mixer_start (GstAggregator * agg) { guint i; GstGLMixer *mix = GST_GL_MIXER (agg); GstElement *element = GST_ELEMENT (agg); if (!GST_AGGREGATOR_CLASS (parent_class)->start (agg)) return FALSE; GST_OBJECT_LOCK (mix); mix->array_buffers = g_ptr_array_new_full (element->numsinkpads, (GDestroyNotify) _free_glmixer_frame_data); mix->frames = g_ptr_array_new_full (element->numsinkpads, NULL); g_ptr_array_set_size (mix->array_buffers, element->numsinkpads); g_ptr_array_set_size (mix->frames, element->numsinkpads); for (i = 0; i < element->numsinkpads; i++) mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData); GST_OBJECT_UNLOCK (mix); return TRUE; }
static gboolean gst_audio_aggregator_negotiated_src_caps (GstAggregator * agg, GstCaps * caps) { GstAudioAggregator *aagg = GST_AUDIO_AGGREGATOR (agg); GstAudioInfo info; if (!gst_audio_info_from_caps (&info, caps)) { GST_WARNING_OBJECT (aagg, "Rejecting invalid caps: %" GST_PTR_FORMAT, caps); return FALSE; } GST_AUDIO_AGGREGATOR_LOCK (aagg); GST_OBJECT_LOCK (aagg); if (!gst_audio_info_is_equal (&info, &aagg->info)) { GST_INFO_OBJECT (aagg, "setting caps to %" GST_PTR_FORMAT, caps); gst_caps_replace (&aagg->current_caps, caps); memcpy (&aagg->info, &info, sizeof (info)); } GST_OBJECT_UNLOCK (aagg); GST_AUDIO_AGGREGATOR_UNLOCK (aagg); /* send caps event later, after stream-start event */ return GST_AGGREGATOR_CLASS (gst_audio_aggregator_parent_class)->negotiated_src_caps (agg, caps); }
static gboolean gst_audiomixer_sink_event (GstAggregator * agg, GstAggregatorPad * aggpad, GstEvent * event) { GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg); gboolean res = TRUE; GST_DEBUG_OBJECT (aggpad, "Got %s event on sink pad", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; gst_event_parse_caps (event, &caps); res = gst_audiomixer_setcaps (audiomixer, GST_PAD_CAST (aggpad), caps); gst_event_unref (event); event = NULL; break; } default: break; } if (event != NULL) return GST_AGGREGATOR_CLASS (parent_class)->sink_event (agg, aggpad, event); return res; }
static gboolean gst_gl_stereo_mix_start (GstAggregator * agg) { guint i; GstGLStereoMix *mix = GST_GL_STEREO_MIX (agg); GstElement *element = GST_ELEMENT (agg); if (!GST_AGGREGATOR_CLASS (parent_class)->start (agg)) return FALSE; GST_OBJECT_LOCK (mix); mix->array_buffers = g_ptr_array_new_full (element->numsinkpads, (GDestroyNotify) _free_glmixer_frame_data); mix->frames = g_ptr_array_new_full (element->numsinkpads, NULL); g_ptr_array_set_size (mix->array_buffers, element->numsinkpads); g_ptr_array_set_size (mix->frames, element->numsinkpads); for (i = 0; i < element->numsinkpads; i++) mix->frames->pdata[i] = g_slice_new0 (GstGLStereoMixFrameData); mix->viewconvert = gst_gl_view_convert_new (); g_object_set (G_OBJECT (mix->viewconvert), "downmix-mode", mix->downmix_mode, NULL); GST_OBJECT_UNLOCK (mix); return TRUE; }
static gboolean gst_audio_aggregator_sink_event (GstAggregator * agg, GstAggregatorPad * aggpad, GstEvent * event) { gboolean res = TRUE; GST_DEBUG_OBJECT (aggpad, "Got %s event on sink pad", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: { const GstSegment *segment; gst_event_parse_segment (event, &segment); if (segment->format != GST_FORMAT_TIME) { GST_ERROR_OBJECT (agg, "Segment of type %s are not supported," " only TIME segments are supported", gst_format_get_name (segment->format)); gst_event_unref (event); event = NULL; res = FALSE; break; } GST_OBJECT_LOCK (agg); if (segment->rate != agg->segment.rate) { GST_ERROR_OBJECT (aggpad, "Got segment event with wrong rate %lf, expected %lf", segment->rate, agg->segment.rate); res = FALSE; gst_event_unref (event); event = NULL; } else if (segment->rate < 0.0) { GST_ERROR_OBJECT (aggpad, "Negative rates not supported yet"); res = FALSE; gst_event_unref (event); event = NULL; } else { GstAudioAggregatorPad *pad = GST_AUDIO_AGGREGATOR_PAD (aggpad); GST_OBJECT_LOCK (pad); pad->priv->new_segment = TRUE; GST_OBJECT_UNLOCK (pad); } GST_OBJECT_UNLOCK (agg); break; } default: break; } if (event != NULL) return GST_AGGREGATOR_CLASS (gst_audio_aggregator_parent_class)->sink_event (agg, aggpad, event); return res; }
static gboolean gst_audiomixer_sink_query (GstAggregator * agg, GstAggregatorPad * aggpad, GstQuery * query) { gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS: { GstCaps *filter, *caps; gst_query_parse_caps (query, &filter); caps = gst_audiomixer_sink_getcaps (agg, GST_PAD (aggpad), filter); gst_query_set_caps_result (query, caps); gst_caps_unref (caps); res = TRUE; break; } default: res = GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, aggpad, query); break; } return res; }
static gboolean gst_mxf_mux_sink_event (GstAggregator * aggregator, GstAggregatorPad * aggpad, GstEvent * event) { GstMXFMux *mux = GST_MXF_MUX (aggregator); gboolean ret = TRUE; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_TAG: /* TODO: do something with the tags */ break; case GST_EVENT_CAPS:{ GstCaps *caps; gst_event_parse_caps (event, &caps); ret = gst_mxf_mux_set_caps (mux, GST_MXF_MUX_PAD (aggpad), caps); break; } default: break; } /* now GstAggregator can take care of the rest, e.g. EOS */ if (ret) ret = GST_AGGREGATOR_CLASS (parent_class)->sink_event (aggregator, aggpad, event); return ret; }
static gboolean gst_audio_aggregator_src_query (GstAggregator * agg, GstQuery * query) { GstAudioAggregator *aagg = GST_AUDIO_AGGREGATOR (agg); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: res = gst_audio_aggregator_query_duration (aagg, query); break; case GST_QUERY_POSITION: { GstFormat format; gst_query_parse_position (query, &format, NULL); GST_OBJECT_LOCK (aagg); switch (format) { case GST_FORMAT_TIME: gst_query_set_position (query, format, gst_segment_to_stream_time (&agg->segment, GST_FORMAT_TIME, agg->segment.position)); res = TRUE; break; case GST_FORMAT_BYTES: if (GST_AUDIO_INFO_BPF (&aagg->info)) { gst_query_set_position (query, format, aagg->priv->offset * GST_AUDIO_INFO_BPF (&aagg->info)); res = TRUE; } break; case GST_FORMAT_DEFAULT: gst_query_set_position (query, format, aagg->priv->offset); res = TRUE; break; default: break; } GST_OBJECT_UNLOCK (aagg); break; } default: res = GST_AGGREGATOR_CLASS (gst_audio_aggregator_parent_class)->src_query (agg, query); break; } return res; }
static gboolean gst_gl_mixer_stop (GstAggregator * agg) { GstGLMixer *mix = GST_GL_MIXER (agg); GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); if (!GST_AGGREGATOR_CLASS (parent_class)->stop (agg)) return FALSE; GST_OBJECT_LOCK (agg); g_ptr_array_free (mix->frames, TRUE); mix->frames = NULL; g_ptr_array_free (mix->array_buffers, TRUE); mix->array_buffers = NULL; GST_OBJECT_UNLOCK (agg); if (mixer_class->reset) mixer_class->reset (mix); if (mix->fbo) { gst_gl_context_del_fbo (mix->context, mix->fbo, mix->depthbuffer); mix->fbo = 0; mix->depthbuffer = 0; } if (mix->download) { gst_object_unref (mix->download); mix->download = NULL; } gst_aggregator_iterate_sinkpads (GST_AGGREGATOR (mix), _clean_upload, NULL); if (mix->priv->query) { gst_query_unref (mix->priv->query); mix->priv->query = NULL; } if (mix->priv->pool) { gst_object_unref (mix->priv->pool); mix->priv->pool = NULL; } if (mix->display) { gst_object_unref (mix->display); mix->display = NULL; } if (mix->context) { gst_object_unref (mix->context); mix->context = NULL; } gst_gl_mixer_reset (mix); return TRUE; }
static gboolean gst_gl_mixer_sink_query (GstAggregator * agg, GstAggregatorPad * bpad, GstQuery * query) { gboolean ret = FALSE; GstGLMixer *mix = GST_GL_MIXER (agg); GST_TRACE ("QUERY %" GST_PTR_FORMAT, query); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_ALLOCATION: { GstQuery *decide_query = NULL; gboolean negotiated; GST_OBJECT_LOCK (mix); if (G_UNLIKELY (!(negotiated = mix->priv->negotiated))) { GST_DEBUG_OBJECT (mix, "not negotiated yet, can't answer ALLOCATION query"); GST_OBJECT_UNLOCK (mix); return FALSE; } if ((decide_query = mix->priv->query)) gst_query_ref (decide_query); GST_OBJECT_UNLOCK (mix); GST_DEBUG_OBJECT (mix, "calling propose allocation with query %" GST_PTR_FORMAT, decide_query); /* pass the query to the propose_allocation vmethod if any */ ret = gst_gl_mixer_propose_allocation (mix, decide_query, query); if (decide_query) gst_query_unref (decide_query); GST_DEBUG_OBJECT (mix, "ALLOCATION ret %d, %" GST_PTR_FORMAT, ret, query); break; } case GST_QUERY_CONTEXT: { ret = gst_gl_handle_context_query ((GstElement *) mix, query, &mix->display); break; } default: ret = GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, bpad, query); break; } return ret; }
static gboolean gst_gl_stereo_mix_src_query (GstAggregator * agg, GstQuery * query) { switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS: return gst_gl_stereo_mix_query_caps (agg->srcpad, agg, query); break; default: break; } return GST_AGGREGATOR_CLASS (parent_class)->src_query (agg, query); }
static gboolean gst_gl_base_mixer_src_query (GstAggregator * agg, GstQuery * query) { gboolean res = FALSE; GstGLBaseMixer *mix = GST_GL_BASE_MIXER (agg); GstGLBaseMixerClass *mix_class = GST_GL_BASE_MIXER_GET_CLASS (mix); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT: { const gchar *context_type; GstContext *context, *old_context; res = gst_gl_handle_context_query ((GstElement *) mix, query, &mix->display, &mix->priv->other_context); if (mix->display) gst_gl_display_filter_gl_api (mix->display, mix_class->supported_gl_api); gst_query_parse_context_type (query, &context_type); if (g_strcmp0 (context_type, "gst.gl.local_context") == 0) { GstStructure *s; gst_query_parse_context (query, &old_context); if (old_context) context = gst_context_copy (old_context); else context = gst_context_new ("gst.gl.local_context", FALSE); s = gst_context_writable_structure (context); gst_structure_set (s, "context", GST_GL_TYPE_CONTEXT, mix->context, NULL); gst_query_set_context (query, context); gst_context_unref (context); res = mix->context != NULL; } GST_LOG_OBJECT (mix, "context query of type %s %i", context_type, res); if (res) return res; break; } default: break; } return GST_AGGREGATOR_CLASS (parent_class)->src_query (agg, query); }
static gboolean gst_mxf_mux_src_event (GstAggregator * aggregator, GstEvent * event) { switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: /* disable seeking for now */ gst_event_unref (event); return FALSE; default: return GST_AGGREGATOR_CLASS (parent_class)->src_event (aggregator, event); break; } g_assert_not_reached (); }
static gboolean gst_gl_stereo_mix_stop (GstAggregator * agg) { GstGLStereoMix *mix = GST_GL_STEREO_MIX (agg); if (!GST_AGGREGATOR_CLASS (parent_class)->stop (agg)) return FALSE; if (mix->viewconvert) { gst_object_unref (mix->viewconvert); mix->viewconvert = NULL; } return TRUE; }
static gboolean gst_gl_stereo_mix_start (GstAggregator * agg) { GstGLStereoMix *mix = GST_GL_STEREO_MIX (agg); if (!GST_AGGREGATOR_CLASS (parent_class)->start (agg)) return FALSE; GST_OBJECT_LOCK (mix); mix->viewconvert = gst_gl_view_convert_new (); g_object_set (G_OBJECT (mix->viewconvert), "downmix-mode", mix->downmix_mode, NULL); GST_OBJECT_UNLOCK (mix); return TRUE; }
static gboolean gst_gl_stereo_mix_stop (GstAggregator * agg) { GstGLStereoMix *mix = GST_GL_STEREO_MIX (agg); if (!GST_AGGREGATOR_CLASS (parent_class)->stop (agg)) return FALSE; GST_OBJECT_LOCK (agg); g_ptr_array_free (mix->frames, TRUE); mix->frames = NULL; g_ptr_array_free (mix->array_buffers, TRUE); mix->array_buffers = NULL; GST_OBJECT_UNLOCK (agg); if (mix->viewconvert) { gst_object_unref (mix->viewconvert); mix->viewconvert = NULL; } return TRUE; }
static gboolean gst_gl_mixer_src_query (GstAggregator * agg, GstQuery * query) { gboolean res = FALSE; GstGLMixer *mix = GST_GL_MIXER (agg); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT: { res = gst_gl_handle_context_query ((GstElement *) mix, query, &mix->display); break; } case GST_QUERY_CAPS: res = gst_gl_mixer_query_caps (agg->srcpad, agg, query); break; default: res = GST_AGGREGATOR_CLASS (parent_class)->src_query (agg, query); break; } return res; }
static gboolean gst_gl_base_mixer_sink_query (GstAggregator * agg, GstAggregatorPad * bpad, GstQuery * query) { gboolean ret = FALSE; GstGLBaseMixer *mix = GST_GL_BASE_MIXER (agg); GstGLBaseMixerClass *mix_class = GST_GL_BASE_MIXER_GET_CLASS (mix); GstGLBaseMixerPad *pad = GST_GL_BASE_MIXER_PAD (bpad); GST_TRACE ("QUERY %" GST_PTR_FORMAT, query); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_ALLOCATION: { GstQuery *decide_query = NULL; GST_OBJECT_LOCK (mix); if (G_UNLIKELY (!mix->priv->negotiated)) { GST_DEBUG_OBJECT (mix, "not negotiated yet, can't answer ALLOCATION query"); GST_OBJECT_UNLOCK (mix); return FALSE; } if ((decide_query = mix->priv->query)) gst_query_ref (decide_query); GST_OBJECT_UNLOCK (mix); GST_DEBUG_OBJECT (mix, "calling propose allocation with query %" GST_PTR_FORMAT, decide_query); /* pass the query to the propose_allocation vmethod if any */ if (mix_class->propose_allocation) ret = mix_class->propose_allocation (mix, pad, decide_query, query); else ret = FALSE; if (decide_query) gst_query_unref (decide_query); GST_DEBUG_OBJECT (mix, "ALLOCATION ret %d, %" GST_PTR_FORMAT, ret, query); return ret; } case GST_QUERY_CONTEXT: { const gchar *context_type; GstContext *context, *old_context; ret = gst_gl_handle_context_query ((GstElement *) mix, query, &mix->display, &mix->priv->other_context); if (mix->display) gst_gl_display_filter_gl_api (mix->display, mix_class->supported_gl_api); gst_query_parse_context_type (query, &context_type); if (g_strcmp0 (context_type, "gst.gl.local_context") == 0) { GstStructure *s; gst_query_parse_context (query, &old_context); if (old_context) context = gst_context_copy (old_context); else context = gst_context_new ("gst.gl.local_context", FALSE); s = gst_context_writable_structure (context); gst_structure_set (s, "context", GST_GL_TYPE_CONTEXT, mix->context, NULL); gst_query_set_context (query, context); gst_context_unref (context); ret = mix->context != NULL; } GST_LOG_OBJECT (mix, "context query of type %s %i", context_type, ret); if (ret) return ret; break; } default: break; } return GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, bpad, query);; }
static gboolean gst_audio_aggregator_src_event (GstAggregator * agg, GstEvent * event) { gboolean result; GstAudioAggregator *aagg = GST_AUDIO_AGGREGATOR (agg); GST_DEBUG_OBJECT (agg->srcpad, "Got %s event on src pad", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_QOS: /* QoS might be tricky */ gst_event_unref (event); return FALSE; case GST_EVENT_NAVIGATION: /* navigation is rather pointless. */ gst_event_unref (event); return FALSE; break; case GST_EVENT_SEEK: { GstSeekFlags flags; gdouble rate; GstSeekType start_type, stop_type; gint64 start, stop; GstFormat seek_format, dest_format; /* parse the seek parameters */ gst_event_parse_seek (event, &rate, &seek_format, &flags, &start_type, &start, &stop_type, &stop); /* Check the seeking parametters before linking up */ if ((start_type != GST_SEEK_TYPE_NONE) && (start_type != GST_SEEK_TYPE_SET)) { result = FALSE; GST_DEBUG_OBJECT (aagg, "seeking failed, unhandled seek type for start: %d", start_type); goto done; } if ((stop_type != GST_SEEK_TYPE_NONE) && (stop_type != GST_SEEK_TYPE_SET)) { result = FALSE; GST_DEBUG_OBJECT (aagg, "seeking failed, unhandled seek type for end: %d", stop_type); goto done; } GST_OBJECT_LOCK (agg); dest_format = agg->segment.format; GST_OBJECT_UNLOCK (agg); if (seek_format != dest_format) { result = FALSE; GST_DEBUG_OBJECT (aagg, "seeking failed, unhandled seek format: %s", gst_format_get_name (seek_format)); goto done; } } break; default: break; } return GST_AGGREGATOR_CLASS (gst_audio_aggregator_parent_class)->src_event (agg, event); done: return result; }
static gboolean gst_gl_base_mixer_start (GstAggregator * agg) { return GST_AGGREGATOR_CLASS (parent_class)->start (agg);; }
static gboolean gst_gl_mixer_sink_query (GstAggregator * agg, GstAggregatorPad * bpad, GstQuery * query) { gboolean ret = FALSE; GstGLMixer *mix = GST_GL_MIXER (agg); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); GST_TRACE ("QUERY %" GST_PTR_FORMAT, query); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS: { GstCaps *filter, *caps; gst_query_parse_caps (query, &filter); caps = gst_gl_mixer_pad_sink_getcaps (GST_PAD (bpad), mix, filter); gst_query_set_caps_result (query, caps); gst_caps_unref (caps); ret = TRUE; break; } case GST_QUERY_ACCEPT_CAPS: { GstCaps *caps; gst_query_parse_accept_caps (query, &caps); ret = gst_gl_mixer_pad_sink_acceptcaps (GST_PAD (bpad), mix, caps); gst_query_set_accept_caps_result (query, ret); ret = TRUE; break; } case GST_QUERY_ALLOCATION: { GstQuery *decide_query = NULL; GST_OBJECT_LOCK (mix); if (G_UNLIKELY (!mix->priv->negotiated)) { GST_DEBUG_OBJECT (mix, "not negotiated yet, can't answer ALLOCATION query"); GST_OBJECT_UNLOCK (mix); return FALSE; } if ((decide_query = mix->priv->query)) gst_query_ref (decide_query); GST_OBJECT_UNLOCK (mix); GST_DEBUG_OBJECT (mix, "calling propose allocation with query %" GST_PTR_FORMAT, decide_query); /* pass the query to the propose_allocation vmethod if any */ ret = gst_gl_mixer_propose_allocation (mix, decide_query, query); if (decide_query) gst_query_unref (decide_query); GST_DEBUG_OBJECT (mix, "ALLOCATION ret %d, %" GST_PTR_FORMAT, ret, query); break; } case GST_QUERY_CONTEXT: { ret = gst_gl_handle_context_query ((GstElement *) mix, query, &mix->display, &mix->other_context); if (mix->display) gst_gl_display_filter_gl_api (mix->display, mix_class->supported_gl_api); break; } default: ret = GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, bpad, query); break; } return ret; }