/* * Sets the caps on deinterlace sinkpad and validates the * caps that is set on the srcpad */ static void deinterlace_set_caps_and_check (GstCaps * input, gboolean must_deinterlace) { GstCaps *othercaps = NULL; GstSegment segment; gst_pad_send_event (sinkpad, gst_event_new_stream_start ("test")); fail_unless (gst_pad_set_caps (sinkpad, input)); gst_segment_init (&segment, GST_FORMAT_TIME); gst_pad_send_event (sinkpad, gst_event_new_segment (&segment)); g_object_get (srcpad, "caps", &othercaps, NULL); if (must_deinterlace) { fail_if (gst_caps_is_interlaced (othercaps)); } else { GstStructure *s; fail_unless (gst_caps_is_interlaced (input) == gst_caps_is_interlaced (othercaps)); othercaps = gst_caps_make_writable (othercaps); s = gst_caps_get_structure (othercaps, 0); gst_structure_remove_field (s, "interlace-mode"); input = gst_caps_make_writable (input); s = gst_caps_get_structure (input, 0); gst_structure_remove_field (s, "interlace-mode"); fail_unless (gst_caps_is_equal (input, othercaps)); } gst_caps_unref (input); gst_caps_unref (othercaps); }
static gboolean prepare_src_pad (MpegTSBase * base, MpegTSParse2 * parse) { GstEvent *event; gchar *stream_id; GstCaps *caps; if (!parse->first) return TRUE; /* If there's no packet_size yet, we can't set caps yet */ if (G_UNLIKELY (base->packetizer->packet_size == 0)) return FALSE; stream_id = gst_pad_create_stream_id (parse->srcpad, GST_ELEMENT_CAST (base), "multi-program"); event = gst_pad_get_sticky_event (parse->parent.sinkpad, GST_EVENT_STREAM_START, 0); if (event) { if (gst_event_parse_group_id (event, &parse->group_id)) parse->have_group_id = TRUE; else parse->have_group_id = FALSE; gst_event_unref (event); } else if (!parse->have_group_id) { parse->have_group_id = TRUE; parse->group_id = gst_util_group_id_next (); } event = gst_event_new_stream_start (stream_id); if (parse->have_group_id) gst_event_set_group_id (event, parse->group_id); gst_pad_push_event (parse->srcpad, event); g_free (stream_id); caps = gst_caps_new_simple ("video/mpegts", "systemstream", G_TYPE_BOOLEAN, TRUE, "packetsize", G_TYPE_INT, base->packetizer->packet_size, NULL); gst_pad_set_caps (parse->srcpad, caps); gst_caps_unref (caps); /* If setting output timestamps, ensure that the output segment is TIME */ if (parse->set_timestamps == FALSE || base->segment.format == GST_FORMAT_TIME) gst_pad_push_event (parse->srcpad, gst_event_new_segment (&base->segment)); else { GstSegment seg; gst_segment_init (&seg, GST_FORMAT_TIME); GST_DEBUG_OBJECT (parse, "Generating time output segment %" GST_SEGMENT_FORMAT, &seg); gst_pad_push_event (parse->srcpad, gst_event_new_segment (&seg)); } parse->first = FALSE; return TRUE; }
static void switch_pads (GstHLSDemux * demux, GstCaps * newcaps) { GstPad *oldpad = demux->srcpad; GST_DEBUG ("Switching pads (oldpad:%p) with caps: %" GST_PTR_FORMAT, oldpad, newcaps); /* First create and activate new pad */ demux->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL); gst_pad_set_event_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_event)); gst_pad_set_query_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_query)); gst_pad_set_element_private (demux->srcpad, demux); gst_pad_set_active (demux->srcpad, TRUE); gst_pad_push_event (demux->srcpad, gst_event_new_stream_start ()); gst_pad_set_caps (demux->srcpad, newcaps); gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad); gst_element_no_more_pads (GST_ELEMENT (demux)); if (oldpad) { /* Push out EOS */ gst_pad_push_event (oldpad, gst_event_new_eos ()); gst_pad_set_active (oldpad, FALSE); gst_element_remove_pad (GST_ELEMENT (demux), oldpad); } }
static void udpsink_test (gboolean use_buffer_lists) { GstSegment segment; GstElement *udpsink; GstPad *srcpad; GstBufferList *list; guint data_size; list = create_buffer_list (&data_size); udpsink = gst_check_setup_element ("udpsink"); if (use_buffer_lists) set_render_list_function (udpsink); srcpad = gst_check_setup_src_pad_by_name (udpsink, &srctemplate, "sink"); gst_element_set_state (udpsink, GST_STATE_PLAYING); gst_pad_set_active (srcpad, TRUE); gst_pad_push_event (srcpad, gst_event_new_stream_start ("hey there!")); gst_segment_init (&segment, GST_FORMAT_TIME); gst_pad_push_event (srcpad, gst_event_new_segment (&segment)); fail_unless_equals_int (gst_pad_push_list (srcpad, list), GST_FLOW_OK); gst_check_teardown_pad_by_name (udpsink, "sink"); gst_check_teardown_element (udpsink); if (use_buffer_lists) fail_unless_equals_int (data_size, render_list_bytes_received); }
static GstFlowReturn gst_dtls_enc_push (GstDtlsEnc * self, GstBuffer * buffer) { GstDtlsBase *base = GST_DTLS_BASE (self); GstEvent *segment_event, *caps_event; gchar *stream_id; stream_id = gst_pad_get_stream_id (base->srcpad); if (stream_id == NULL) { stream_id = gst_pad_get_stream_id (base->sinkpad); if (stream_id == NULL) { stream_id = gst_pad_create_stream_id (base->srcpad, GST_ELEMENT (base), NULL); } gst_pad_push_event (base->srcpad, gst_event_new_stream_start (stream_id)); } g_free (stream_id); caps_event = gst_pad_get_sticky_event (base->srcpad, GST_EVENT_CAPS, 0); if (caps_event == NULL) { GstCaps *caps = gst_caps_from_string ("application/x-dtls"); caps_event = gst_event_new_caps (caps); gst_caps_unref (caps); gst_pad_push_event (base->srcpad, caps_event); } else { gst_event_unref (caps_event); } segment_event = gst_pad_get_sticky_event (base->srcpad, GST_EVENT_SEGMENT, 0); if (segment_event == NULL) { GstSegment *segment = gst_segment_new (); gst_segment_init (segment, GST_FORMAT_BYTES); segment_event = gst_event_new_segment (segment); gst_segment_free (segment); gst_pad_push_event (base->srcpad, segment_event); } else { gst_event_unref (segment_event); } GST_OBJECT_LOCK (self); if (self->src_buffer && self->running_thread == g_thread_self ()) { g_assert (gst_buffer_get_size (buffer) != 181); gst_buffer_copy_into (buffer, self->src_buffer, GST_BUFFER_COPY_METADATA, 0, -1); } GST_OBJECT_UNLOCK (self); return gst_pad_push (base->srcpad, buffer); }
static gboolean gst_droidcamsrc_mode_negotiate_pad (GstDroidCamSrcMode * mode, GstPad * pad, gboolean force) { GstDroidCamSrcPad *data = gst_pad_get_element_private (pad); /* take pad lock */ g_mutex_lock (&data->lock); if (!force) { if (!gst_pad_check_reconfigure (data->pad)) { g_mutex_unlock (&data->lock); return TRUE; } } /* * stream start * we must send it before we send our CAPS event */ if (G_UNLIKELY (data->open_stream)) { gchar *stream_id; GstEvent *event; stream_id = gst_pad_create_stream_id (data->pad, GST_ELEMENT_CAST (mode->src), GST_PAD_NAME (data->pad)); GST_DEBUG_OBJECT (pad, "Pushing STREAM_START for pad"); event = gst_event_new_stream_start (stream_id); gst_event_set_group_id (event, gst_util_group_id_next ()); if (!gst_pad_push_event (data->pad, event)) { GST_ERROR_OBJECT (mode->src, "failed to push STREAM_START event for pad %s", GST_PAD_NAME (data->pad)); } g_free (stream_id); data->open_stream = FALSE; } /* negotiate */ if (!data->negotiate (data)) { GST_ELEMENT_ERROR (mode->src, STREAM, FORMAT, (NULL), ("failed to negotiate %s.", GST_PAD_NAME (data->pad))); g_mutex_unlock (&data->lock); return FALSE; } /* toss pad queue */ g_queue_foreach (data->queue, (GFunc) gst_buffer_unref, NULL); g_queue_clear (data->queue); /* unlock */ g_mutex_unlock (&data->lock); return TRUE; }
static GstEvent * create_new_stream_start_event (GstHarness * h, gpointer data) { guint *counter = data; gchar *stream_id = g_strdup_printf ("streamid/%d", *counter); GstEvent *event = gst_event_new_stream_start (stream_id); g_free (stream_id); (*counter)++; return event; }
static void gst_decklink_src_send_initial_events (GstDecklinkSrc * src) { GstSegment segment; GstEvent *event; guint group_id; guint32 audio_id, video_id; gchar stream_id[9]; /* stream-start */ audio_id = g_random_int (); video_id = g_random_int (); while (video_id == audio_id) video_id = g_random_int (); group_id = gst_util_group_id_next (); g_snprintf (stream_id, sizeof (stream_id), "%08x", audio_id); event = gst_event_new_stream_start (stream_id); gst_event_set_group_id (event, group_id); gst_pad_push_event (src->audiosrcpad, event); g_snprintf (stream_id, sizeof (stream_id), "%08x", video_id); event = gst_event_new_stream_start (stream_id); gst_event_set_group_id (event, group_id); gst_pad_push_event (src->videosrcpad, event); /* segment */ gst_segment_init (&segment, GST_FORMAT_TIME); event = gst_event_new_segment (&segment); gst_pad_push_event (src->videosrcpad, gst_event_ref (event)); gst_pad_push_event (src->audiosrcpad, event); /* caps */ gst_pad_push_event (src->audiosrcpad, gst_event_new_caps (gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16LE", "channels", G_TYPE_INT, 2, "rate", G_TYPE_INT, 48000, "layout", G_TYPE_STRING, "interleaved", NULL))); gst_pad_push_event (src->videosrcpad, gst_event_new_caps (gst_decklink_mode_get_caps (src->mode))); }
static inline void _push_mandatory_events (GstAggregator * self) { GstAggregatorPrivate *priv = self->priv; if (g_atomic_int_get (&self->priv->send_stream_start)) { gchar s_id[32]; GST_INFO_OBJECT (self, "pushing stream start"); /* stream-start (FIXME: create id based on input ids) */ g_snprintf (s_id, sizeof (s_id), "agg-%08x", g_random_int ()); if (!gst_pad_push_event (self->srcpad, gst_event_new_stream_start (s_id))) { GST_WARNING_OBJECT (self->srcpad, "Sending stream start event failed"); } g_atomic_int_set (&self->priv->send_stream_start, FALSE); } if (self->priv->srccaps) { GST_INFO_OBJECT (self, "pushing caps: %" GST_PTR_FORMAT, self->priv->srccaps); if (!gst_pad_push_event (self->srcpad, gst_event_new_caps (self->priv->srccaps))) { GST_WARNING_OBJECT (self->srcpad, "Sending caps event failed"); } gst_caps_unref (self->priv->srccaps); self->priv->srccaps = NULL; } if (g_atomic_int_get (&self->priv->send_segment)) { if (!g_atomic_int_get (&self->priv->flush_seeking)) { GstEvent *segev = gst_event_new_segment (&self->segment); if (!self->priv->seqnum) self->priv->seqnum = gst_event_get_seqnum (segev); else gst_event_set_seqnum (segev, self->priv->seqnum); GST_DEBUG_OBJECT (self, "pushing segment %" GST_PTR_FORMAT, segev); gst_pad_push_event (self->srcpad, segev); g_atomic_int_set (&self->priv->send_segment, FALSE); } } if (priv->tags && priv->tags_changed) { gst_pad_push_event (self->srcpad, gst_event_new_tag (gst_tag_list_ref (priv->tags))); priv->tags_changed = FALSE; } }
static void gst_check_setup_events_textoverlay (GstPad * srcpad, GstElement * element, GstCaps * caps, GstFormat format, const gchar * stream_id) { GstSegment segment; gst_segment_init (&segment, format); fail_unless (gst_pad_push_event (srcpad, gst_event_new_stream_start (stream_id))); if (caps) fail_unless (gst_pad_push_event (srcpad, gst_event_new_caps (caps))); fail_unless (gst_pad_push_event (srcpad, gst_event_new_segment (&segment))); }
static void send_startup_events (void) { GstCaps *caps; fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("randomvalue"))); /* push caps */ caps = gst_caps_new_simple ("audio/x-test-custom", "channels", G_TYPE_INT, 2, "rate", G_TYPE_INT, 44100, NULL); fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_caps (caps))); }
static GstFlowReturn gst_agregator_collected (GstCollectPads * pads, gpointer user_data) { GstAggregator *aggregator = GST_AGGREGATOR (user_data); GstBuffer *inbuf; GstCollectData *collect_data = NULL; guint outsize = 0; GSList *walk; walk = pads->data; for (walk = pads->data; walk; walk = walk->next) { GstCollectData *tmp = (GstCollectData *) walk->data; if (tmp->buffer) { collect_data = tmp; break; } } /* can only happen when no pads to collect or all EOS */ if (collect_data == NULL) goto eos; outsize = gst_buffer_get_size (collect_data->buffer); inbuf = gst_collect_pads_take_buffer (pads, collect_data, outsize); if (!inbuf) goto eos; if (aggregator->first) { GstSegment segment; gst_segment_init (&segment, GST_FORMAT_BYTES); gst_pad_push_event (aggregator->srcpad, gst_event_new_stream_start ("test")); gst_pad_push_event (aggregator->srcpad, gst_event_new_segment (&segment)); aggregator->first = FALSE; } /* just forward the first buffer */ GST_DEBUG_OBJECT (aggregator, "forward buffer %p", inbuf); return gst_pad_push (aggregator->srcpad, inbuf); /* ERRORS */ eos: { GST_DEBUG_OBJECT (aggregator, "no data available, must be EOS"); gst_pad_push_event (aggregator->srcpad, gst_event_new_eos ()); return GST_FLOW_EOS; } }
static void send_startup_events (void) { GstCaps *caps; fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("randomvalue"))); /* push caps */ caps = gst_caps_new_simple ("audio/x-raw", "rate", G_TYPE_INT, TEST_AUDIO_RATE, "channels", G_TYPE_INT, TEST_AUDIO_CHANNELS, "format", G_TYPE_STRING, "S16LE", "layout", G_TYPE_STRING, "interleaved", NULL); fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_caps (caps))); gst_caps_unref (caps); }
static void send_startup_events (void) { GstCaps *caps; fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("randomvalue"))); /* push caps */ caps = gst_caps_new_simple ("video/x-test-custom", "width", G_TYPE_INT, TEST_VIDEO_WIDTH, "height", G_TYPE_INT, TEST_VIDEO_HEIGHT, "framerate", GST_TYPE_FRACTION, TEST_VIDEO_FPS_N, TEST_VIDEO_FPS_D, NULL); fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_caps (caps))); gst_caps_unref (caps); }
static gboolean gst_rtp_mux_setcaps (GstPad * pad, GstRTPMux * rtp_mux, GstCaps * caps) { GstStructure *structure; gboolean ret = FALSE; GstRTPMuxPadPrivate *padpriv; structure = gst_caps_get_structure (caps, 0); if (!structure) return FALSE; GST_OBJECT_LOCK (rtp_mux); padpriv = gst_pad_get_element_private (pad); if (padpriv && gst_structure_get_uint (structure, "timestamp-offset", &padpriv->timestamp_offset)) { padpriv->have_timestamp_offset = TRUE; } GST_OBJECT_UNLOCK (rtp_mux); caps = gst_caps_copy (caps); gst_caps_set_simple (caps, "timestamp-offset", G_TYPE_UINT, rtp_mux->ts_base, "seqnum-offset", G_TYPE_UINT, rtp_mux->seqnum_base, NULL); if (rtp_mux->send_stream_start) { gchar s_id[32]; /* stream-start (FIXME: create id based on input ids) */ g_snprintf (s_id, sizeof (s_id), "interleave-%08x", g_random_int ()); gst_pad_push_event (rtp_mux->srcpad, gst_event_new_stream_start (s_id)); rtp_mux->send_stream_start = FALSE; } GST_DEBUG_OBJECT (rtp_mux, "setting caps %" GST_PTR_FORMAT " on src pad..", caps); ret = gst_pad_set_caps (rtp_mux->srcpad, caps); gst_structure_get_uint (structure, "ssrc", &rtp_mux->current_ssrc); gst_caps_unref (caps); return ret; }
static void gst_interleave_send_stream_start (GstInterleave * self) { GST_OBJECT_LOCK (self); if (self->send_stream_start) { gchar s_id[32]; self->send_stream_start = FALSE; GST_OBJECT_UNLOCK (self); /* stream-start (FIXME: create id based on input ids) */ g_snprintf (s_id, sizeof (s_id), "interleave-%08x", g_random_int ()); gst_pad_push_event (self->src, gst_event_new_stream_start (s_id)); } else { GST_OBJECT_UNLOCK (self); } }
static gpointer push_buffer (gpointer user_data) { GstFlowReturn flow; GstCaps *caps; TestData *test_data = (TestData *) user_data; gst_pad_push_event (test_data->pad, gst_event_new_stream_start ("test")); caps = gst_caps_new_empty_simple ("foo/x-bar"); gst_pad_push_event (test_data->pad, gst_event_new_caps (caps)); gst_caps_unref (caps); flow = gst_pad_push (test_data->pad, test_data->buffer); fail_unless (flow == GST_FLOW_OK, "got flow %s instead of OK", gst_flow_get_name (flow)); return NULL; }
static gpointer push_vbuffers (gpointer data) { GstSegment segment; GstPad *pad = data; gint i; GstClockTime timestamp = 0; if (videodelay) g_usleep (2000); if (late_video) timestamp = 50 * GST_MSECOND; gst_pad_send_event (pad, gst_event_new_stream_start ("test")); gst_segment_init (&segment, GST_FORMAT_TIME); gst_pad_send_event (pad, gst_event_new_segment (&segment)); for (i = 0; i < n_vbuffers; i++) { GstBuffer *buf = gst_buffer_new_and_alloc (1000); GstClockTime *rtime = g_new (GstClockTime, 1); gst_buffer_memset (buf, 0, i, 1); GST_BUFFER_TIMESTAMP (buf) = timestamp; timestamp += 25 * GST_MSECOND; GST_BUFFER_DURATION (buf) = timestamp - GST_BUFFER_TIMESTAMP (buf); *rtime = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, timestamp); g_queue_push_tail (&v_timestamp_q, rtime); if (i == 4) { if (video_gaps) timestamp += 10 * GST_MSECOND; else if (video_overlaps) timestamp -= 10 * GST_MSECOND; } fail_unless (gst_pad_chain (pad, buf) == GST_FLOW_OK); } gst_pad_send_event (pad, gst_event_new_eos ()); return NULL; }
static GstElement * setup_wavpackenc (void) { GstElement *wavpackenc; GST_DEBUG ("setup_wavpackenc"); wavpackenc = gst_check_setup_element ("wavpackenc"); mysrcpad = gst_check_setup_src_pad (wavpackenc, &srctemplate); mysinkpad = gst_check_setup_sink_pad (wavpackenc, &sinktemplate); gst_pad_set_active (mysrcpad, TRUE); gst_pad_set_active (mysinkpad, TRUE); fail_unless (gst_element_set_state (wavpackenc, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); bus = gst_bus_new (); gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test-silence")); return wavpackenc; }
/* prepare the source pad for output */ static gboolean mpegpsdemux_prepare_srcpad (MpegPsMux * mux) { GstSegment segment; GValue val = { 0, }; GList *headers, *l; GstCaps *caps; gchar s_id[32]; /* stream-start (FIXME: create id based on input ids) */ g_snprintf (s_id, sizeof (s_id), "mpegpsmux-%08x", g_random_int ()); gst_pad_push_event (mux->srcpad, gst_event_new_stream_start (s_id)); caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, TRUE, NULL); headers = psmux_get_stream_headers (mux->psmux); g_value_init (&val, GST_TYPE_ARRAY); for (l = headers; l != NULL; l = l->next) { GValue buf_val = { 0, }; g_value_init (&buf_val, GST_TYPE_BUFFER); gst_value_take_buffer (&buf_val, GST_BUFFER (l->data)); l->data = NULL; gst_value_array_append_value (&val, &buf_val); g_value_unset (&buf_val); } gst_caps_set_value (caps, "streamheader", &val); g_value_unset (&val); g_list_free (headers); /* Set caps on src pad and push new segment */ gst_pad_push_event (mux->srcpad, gst_event_new_caps (caps)); gst_caps_unref (caps); gst_segment_init (&segment, GST_FORMAT_BYTES); gst_pad_push_event (mux->srcpad, gst_event_new_segment (&segment)); return TRUE; }
static void push_newsegment_events (GList * input_pads) { GstSegment seg; GList *l; seg.flags = GST_SEGMENT_FLAG_NONE; seg.rate = seg.applied_rate = 1.0; seg.format = GST_FORMAT_BYTES; seg.base = 0; seg.start = 0; seg.stop = -1; seg.time = 0; seg.position = 0; seg.duration = -1; for (l = input_pads; l; l = l->next) { GstPad *pad = l->data; gst_pad_push_event (pad, gst_event_new_stream_start ("test")); gst_pad_push_event (pad, gst_event_new_segment (&seg)); } }
static gboolean gst_musepack_stream_init (GstMusepackDec * musepackdec) { mpc_streaminfo i; GstTagList *tags; GstCaps *caps; gchar *stream_id; /* set up reading */ gst_musepack_init_reader (musepackdec->r, musepackdec); musepackdec->d = mpc_demux_init (musepackdec->r); if (!musepackdec->d) { GST_ELEMENT_ERROR (musepackdec, STREAM, WRONG_TYPE, (NULL), (NULL)); return FALSE; } mpc_demux_get_info (musepackdec->d, &i); stream_id = gst_pad_create_stream_id (musepackdec->srcpad, GST_ELEMENT_CAST (musepackdec), NULL); gst_pad_push_event (musepackdec->srcpad, gst_event_new_stream_start (stream_id)); g_free (stream_id); /* capsnego */ caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, GST_MPC_FORMAT, "layout", G_TYPE_STRING, "interleaved", "channels", G_TYPE_INT, i.channels, "rate", G_TYPE_INT, i.sample_freq, NULL); gst_pad_use_fixed_caps (musepackdec->srcpad); if (!gst_pad_set_caps (musepackdec->srcpad, caps)) { GST_ELEMENT_ERROR (musepackdec, CORE, NEGOTIATION, (NULL), (NULL)); return FALSE; } g_atomic_int_set (&musepackdec->bps, 4 * i.channels); g_atomic_int_set (&musepackdec->rate, i.sample_freq); musepackdec->segment.position = 0; musepackdec->segment.duration = mpc_streaminfo_get_length_samples (&i); /* send basic tags */ tags = gst_tag_list_new_empty (); gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_AUDIO_CODEC, "Musepack", NULL); if (i.encoder[0] != '\0' && i.encoder_version > 0) { gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, i.encoder, GST_TAG_ENCODER_VERSION, i.encoder_version, NULL); } if (i.bitrate > 0) { gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE, i.bitrate, NULL); } else if (i.average_bitrate > 0.0) { gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE, (guint) i.average_bitrate, NULL); } if (i.gain_title != 0 || i.gain_album != 0) { gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TRACK_GAIN, (gdouble) i.gain_title / 100.0, GST_TAG_ALBUM_GAIN, (gdouble) i.gain_album / 100.0, NULL); } if (i.peak_title != 0 && i.peak_title != 32767 && i.peak_album != 0 && i.peak_album != 32767) { gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TRACK_PEAK, (gdouble) i.peak_title / 32767.0, GST_TAG_ALBUM_PEAK, (gdouble) i.peak_album / 32767.0, NULL); } GST_LOG_OBJECT (musepackdec, "Posting tags: %" GST_PTR_FORMAT, tags); gst_pad_push_event (musepackdec->srcpad, gst_event_new_tag (tags)); return TRUE; }
static void test_basic (const gchar * elem_name, const gchar * sink2, int count, check_cb cb) { GstElement *rtpmux = NULL; GstPad *reqpad1 = NULL; GstPad *reqpad2 = NULL; GstPad *src1 = NULL; GstPad *src2 = NULL; GstPad *sink = NULL; GstBuffer *inbuf = NULL; GstCaps *src1caps = NULL; GstCaps *src2caps = NULL; GstCaps *sinkcaps = NULL; GstCaps *caps; GstSegment segment; int i; rtpmux = gst_check_setup_element (elem_name); reqpad1 = gst_element_get_request_pad (rtpmux, "sink_1"); fail_unless (reqpad1 != NULL); reqpad2 = gst_element_get_request_pad (rtpmux, sink2); fail_unless (reqpad2 != NULL); sink = gst_check_setup_sink_pad_by_name (rtpmux, &sinktemplate, "src"); src1 = gst_pad_new_from_static_template (&srctemplate, "src"); src2 = gst_pad_new_from_static_template (&srctemplate, "src"); fail_unless (gst_pad_link (src1, reqpad1) == GST_PAD_LINK_OK); fail_unless (gst_pad_link (src2, reqpad2) == GST_PAD_LINK_OK); gst_pad_set_query_function (src1, query_func); gst_pad_set_query_function (src2, query_func); gst_pad_set_query_function (sink, query_func); gst_pad_set_event_function (sink, event_func); g_object_set_data (G_OBJECT (src1), "caps", &src1caps); g_object_set_data (G_OBJECT (src2), "caps", &src2caps); g_object_set_data (G_OBJECT (sink), "caps", &sinkcaps); src1caps = gst_caps_new_simple ("application/x-rtp", "clock-rate", G_TYPE_INT, 1, "ssrc", G_TYPE_UINT, 11, NULL); src2caps = gst_caps_new_simple ("application/x-rtp", "clock-rate", G_TYPE_INT, 2, "ssrc", G_TYPE_UINT, 12, NULL); sinkcaps = gst_caps_new_simple ("application/x-rtp", "clock-rate", G_TYPE_INT, 3, "ssrc", G_TYPE_UINT, 13, NULL); caps = gst_pad_peer_query_caps (src1, NULL); fail_unless (gst_caps_is_empty (caps)); gst_caps_unref (caps); gst_caps_set_simple (src2caps, "clock-rate", G_TYPE_INT, 3, NULL); caps = gst_pad_peer_query_caps (src1, NULL); gst_caps_unref (caps); g_object_set (rtpmux, "seqnum-offset", 100, "timestamp-offset", 1000, "ssrc", 55, NULL); fail_unless (gst_element_set_state (rtpmux, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS); gst_pad_set_active (sink, TRUE); gst_pad_set_active (src1, TRUE); gst_pad_set_active (src2, TRUE); fail_unless (gst_pad_push_event (src1, gst_event_new_stream_start ("stream1"))); fail_unless (gst_pad_push_event (src2, gst_event_new_stream_start ("stream2"))); gst_caps_set_simple (sinkcaps, "payload", G_TYPE_INT, 98, "seqnum-offset", G_TYPE_UINT, 100, "timestamp-offset", G_TYPE_UINT, 1000, "ssrc", G_TYPE_UINT, 66, NULL); caps = gst_caps_new_simple ("application/x-rtp", "payload", G_TYPE_INT, 98, "clock-rate", G_TYPE_INT, 3, "seqnum-offset", G_TYPE_UINT, 56, "timestamp-offset", G_TYPE_UINT, 57, "ssrc", G_TYPE_UINT, 66, NULL); fail_unless (gst_pad_set_caps (src1, caps)); gst_caps_unref (caps); caps = gst_pad_peer_query_caps (sink, NULL); fail_if (gst_caps_is_empty (caps)); gst_segment_init (&segment, GST_FORMAT_TIME); segment.start = 100000; fail_unless (gst_pad_push_event (src1, gst_event_new_segment (&segment))); segment.start = 0; fail_unless (gst_pad_push_event (src2, gst_event_new_segment (&segment))); for (i = 0; i < count; i++) { GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT; inbuf = gst_rtp_buffer_new_allocate (10, 0, 0); GST_BUFFER_PTS (inbuf) = i * 1000 + 100000; GST_BUFFER_DURATION (inbuf) = 1000; gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer); gst_rtp_buffer_set_version (&rtpbuffer, 2); gst_rtp_buffer_set_payload_type (&rtpbuffer, 98); gst_rtp_buffer_set_ssrc (&rtpbuffer, 44); gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i); gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i); gst_rtp_buffer_unmap (&rtpbuffer); fail_unless (gst_pad_push (src1, inbuf) == GST_FLOW_OK); if (buffers) fail_unless (GST_BUFFER_PTS (buffers->data) == i * 1000, "%lld", GST_BUFFER_PTS (buffers->data)); cb (src2, i); g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL); g_list_free (buffers); buffers = NULL; } gst_pad_set_active (sink, FALSE); gst_pad_set_active (src1, FALSE); gst_pad_set_active (src2, FALSE); fail_unless (gst_element_set_state (rtpmux, GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS); gst_check_teardown_pad_by_name (rtpmux, "src"); gst_object_unref (reqpad1); gst_object_unref (reqpad2); gst_check_teardown_pad_by_name (rtpmux, "sink_1"); gst_check_teardown_pad_by_name (rtpmux, sink2); gst_element_release_request_pad (rtpmux, reqpad1); gst_element_release_request_pad (rtpmux, reqpad2); gst_caps_unref (caps); gst_caps_replace (&src1caps, NULL); gst_caps_replace (&src2caps, NULL); gst_caps_replace (&sinkcaps, NULL); gst_check_teardown_element (rtpmux); }
static void gst_type_find_element_loop (GstPad * pad) { GstTypeFindElement *typefind; GstFlowReturn ret = GST_FLOW_OK; typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); if (typefind->need_stream_start) { gchar *stream_id; GstEvent *event; stream_id = gst_pad_create_stream_id (typefind->src, GST_ELEMENT_CAST (typefind), NULL); GST_DEBUG_OBJECT (typefind, "Pushing STREAM_START"); event = gst_event_new_stream_start (stream_id); gst_event_set_group_id (event, gst_util_group_id_next ()); gst_pad_push_event (typefind->src, event); typefind->need_stream_start = FALSE; g_free (stream_id); } if (typefind->mode == MODE_TYPEFIND) { GstPad *peer = NULL; GstCaps *found_caps = NULL; GstTypeFindProbability probability = GST_TYPE_FIND_NONE; GST_DEBUG_OBJECT (typefind, "find type in pull mode"); GST_OBJECT_LOCK (typefind); if (typefind->force_caps) { found_caps = gst_caps_ref (typefind->force_caps); probability = GST_TYPE_FIND_MAXIMUM; } GST_OBJECT_UNLOCK (typefind); if (!found_caps) { peer = gst_pad_get_peer (pad); if (peer) { gint64 size; gchar *ext; if (!gst_pad_query_duration (peer, GST_FORMAT_BYTES, &size)) { GST_WARNING_OBJECT (typefind, "Could not query upstream length!"); gst_object_unref (peer); ret = GST_FLOW_ERROR; goto pause; } /* the size if 0, we cannot continue */ if (size == 0) { /* keep message in sync with message in sink event handler */ GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (_("Stream contains no data.")), ("Can't typefind empty stream")); gst_object_unref (peer); ret = GST_FLOW_ERROR; goto pause; } ext = gst_type_find_get_extension (typefind, pad); found_caps = gst_type_find_helper_get_range (GST_OBJECT_CAST (peer), GST_OBJECT_PARENT (peer), (GstTypeFindHelperGetRangeFunction) (GST_PAD_GETRANGEFUNC (peer)), (guint64) size, ext, &probability); g_free (ext); GST_DEBUG ("Found caps %" GST_PTR_FORMAT, found_caps); gst_object_unref (peer); } } if (!found_caps || probability < typefind->min_probability) { GST_DEBUG ("Trying to guess using extension"); gst_caps_replace (&found_caps, NULL); found_caps = gst_type_find_guess_by_extension (typefind, pad, &probability); } if (!found_caps || probability < typefind->min_probability) { GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL)); gst_caps_replace (&found_caps, NULL); ret = GST_FLOW_ERROR; goto pause; } GST_DEBUG ("Emiting found caps %" GST_PTR_FORMAT, found_caps); gst_type_find_element_emit_have_type (typefind, probability, found_caps); typefind->mode = MODE_NORMAL; gst_caps_unref (found_caps); } else if (typefind->mode == MODE_NORMAL) { GstBuffer *outbuf = NULL; if (typefind->need_segment) { typefind->need_segment = FALSE; gst_pad_push_event (typefind->src, gst_event_new_segment (&typefind->segment)); } /* Pull 4k blocks and send downstream */ ret = gst_pad_pull_range (typefind->sink, typefind->offset, 4096, &outbuf); if (ret != GST_FLOW_OK) goto pause; typefind->offset += gst_buffer_get_size (outbuf); ret = gst_pad_push (typefind->src, outbuf); if (ret != GST_FLOW_OK) goto pause; } else { /* Error out */ ret = GST_FLOW_ERROR; goto pause; } return; pause: { const gchar *reason = gst_flow_get_name (ret); gboolean push_eos = FALSE; GST_LOG_OBJECT (typefind, "pausing task, reason %s", reason); gst_pad_pause_task (typefind->sink); if (ret == GST_FLOW_EOS) { /* perform EOS logic */ if (typefind->segment.flags & GST_SEGMENT_FLAG_SEGMENT) { gint64 stop; /* for segment playback we need to post when (in stream time) * we stopped, this is either stop (when set) or the duration. */ if ((stop = typefind->segment.stop) == -1) stop = typefind->offset; GST_LOG_OBJECT (typefind, "Sending segment done, at end of segment"); gst_element_post_message (GST_ELEMENT (typefind), gst_message_new_segment_done (GST_OBJECT (typefind), GST_FORMAT_BYTES, stop)); gst_pad_push_event (typefind->src, gst_event_new_segment_done (GST_FORMAT_BYTES, stop)); } else { push_eos = TRUE; } } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { /* for fatal errors we post an error message */ GST_ELEMENT_ERROR (typefind, STREAM, FAILED, (NULL), ("stream stopped, reason %s", reason)); push_eos = TRUE; } if (push_eos) { /* send EOS, and prevent hanging if no streams yet */ GST_LOG_OBJECT (typefind, "Sending EOS, at end of stream"); gst_pad_push_event (typefind->src, gst_event_new_eos ()); } return; } }
static gboolean gst_rtp_mux_setcaps (GstPad * pad, GstRTPMux * rtp_mux, GstCaps * caps) { GstStructure *structure; gboolean ret = FALSE; GstRTPMuxPadPrivate *padpriv; GstCaps *peercaps; if (!gst_caps_is_fixed (caps)) return FALSE; peercaps = gst_pad_peer_query_caps (rtp_mux->srcpad, NULL); if (peercaps) { GstCaps *tcaps, *othercaps;; tcaps = gst_pad_get_pad_template_caps (pad); othercaps = gst_caps_intersect_full (peercaps, tcaps, GST_CAPS_INTERSECT_FIRST); if (gst_caps_get_size (othercaps) > 0) { structure = gst_caps_get_structure (othercaps, 0); GST_OBJECT_LOCK (rtp_mux); if (gst_structure_get_uint (structure, "ssrc", &rtp_mux->current_ssrc)) { GST_DEBUG_OBJECT (pad, "Use downstream ssrc: %x", rtp_mux->current_ssrc); rtp_mux->have_ssrc = TRUE; } GST_OBJECT_UNLOCK (rtp_mux); } gst_caps_unref (othercaps); gst_caps_unref (peercaps); gst_caps_unref (tcaps); } structure = gst_caps_get_structure (caps, 0); if (!structure) return FALSE; GST_OBJECT_LOCK (rtp_mux); padpriv = gst_pad_get_element_private (pad); if (padpriv && gst_structure_get_uint (structure, "timestamp-offset", &padpriv->timestamp_offset)) { padpriv->have_timestamp_offset = TRUE; } caps = gst_caps_copy (caps); /* if we don't have a specified ssrc, first try to take one from the caps, and if that fails, generate one */ if (!rtp_mux->have_ssrc) { if (rtp_mux->ssrc_random) { if (!gst_structure_get_uint (structure, "ssrc", &rtp_mux->current_ssrc)) rtp_mux->current_ssrc = g_random_int (); rtp_mux->have_ssrc = TRUE; } } gst_caps_set_simple (caps, "timestamp-offset", G_TYPE_UINT, rtp_mux->ts_base, "seqnum-offset", G_TYPE_UINT, rtp_mux->seqnum_base, "ssrc", G_TYPE_UINT, rtp_mux->current_ssrc, NULL); GST_OBJECT_UNLOCK (rtp_mux); if (rtp_mux->send_stream_start) { gchar s_id[32]; /* stream-start (FIXME: create id based on input ids) */ g_snprintf (s_id, sizeof (s_id), "interleave-%08x", g_random_int ()); gst_pad_push_event (rtp_mux->srcpad, gst_event_new_stream_start (s_id)); rtp_mux->send_stream_start = FALSE; } GST_DEBUG_OBJECT (rtp_mux, "setting caps %" GST_PTR_FORMAT " on src pad..", caps); ret = gst_pad_set_caps (rtp_mux->srcpad, caps); gst_caps_unref (caps); return ret; }
static GstFlowReturn gst_interleave_collected (GstCollectPads * pads, GstInterleave * self) { guint size; GstBuffer *outbuf = NULL; GstFlowReturn ret = GST_FLOW_OK; GSList *collected; guint nsamples; guint ncollected = 0; gboolean empty = TRUE; gint width = self->width / 8; GstMapInfo write_info; GstClockTime timestamp = -1; /* FIXME: send caps and tags after stream-start */ #if 0 if (self->send_stream_start) { gchar s_id[32]; /* stream-start (FIXME: create id based on input ids) */ g_snprintf (s_id, sizeof (s_id), "interleave-%08x", g_random_int ()); gst_pad_push_event (self->src, gst_event_new_stream_start (s_id)); self->send_stream_start = FALSE; } #endif size = gst_collect_pads_available (pads); if (size == 0) goto eos; g_return_val_if_fail (self->func != NULL, GST_FLOW_NOT_NEGOTIATED); g_return_val_if_fail (self->width > 0, GST_FLOW_NOT_NEGOTIATED); g_return_val_if_fail (self->channels > 0, GST_FLOW_NOT_NEGOTIATED); g_return_val_if_fail (self->rate > 0, GST_FLOW_NOT_NEGOTIATED); g_return_val_if_fail (size % width == 0, GST_FLOW_ERROR); GST_DEBUG_OBJECT (self, "Starting to collect %u bytes from %d channels", size, self->channels); nsamples = size / width; outbuf = gst_buffer_new_allocate (NULL, size * self->channels, NULL); if (outbuf == NULL || gst_buffer_get_size (outbuf) < size * self->channels) { gst_buffer_unref (outbuf); return GST_FLOW_NOT_NEGOTIATED; } gst_buffer_map (outbuf, &write_info, GST_MAP_WRITE); memset (write_info.data, 0, size * self->channels); for (collected = pads->data; collected != NULL; collected = collected->next) { GstCollectData *cdata; GstBuffer *inbuf; guint8 *outdata; GstMapInfo input_info; cdata = (GstCollectData *) collected->data; inbuf = gst_collect_pads_take_buffer (pads, cdata, size); if (inbuf == NULL) { GST_DEBUG_OBJECT (cdata->pad, "No buffer available"); goto next; } ncollected++; gst_buffer_map (inbuf, &input_info, GST_MAP_READ); if (timestamp == -1) timestamp = GST_BUFFER_TIMESTAMP (inbuf); if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) goto next; empty = FALSE; outdata = write_info.data + width * GST_INTERLEAVE_PAD_CAST (cdata->pad)->channel; self->func (outdata, input_info.data, self->channels, nsamples); gst_buffer_unmap (inbuf, &input_info); next: if (inbuf) gst_buffer_unref (inbuf); } if (ncollected == 0) { gst_buffer_unmap (outbuf, &write_info); goto eos; } GST_OBJECT_LOCK (self); if (self->pending_segment) { GstEvent *event; GstSegment segment; event = self->pending_segment; self->pending_segment = NULL; GST_OBJECT_UNLOCK (self); /* convert the input segment to time now */ gst_event_copy_segment (event, &segment); if (segment.format != GST_FORMAT_TIME) { gst_event_unref (event); /* not time, convert */ switch (segment.format) { case GST_FORMAT_BYTES: segment.start *= width; if (segment.stop != -1) segment.stop *= width; if (segment.position != -1) segment.position *= width; /* fallthrough for the samples case */ case GST_FORMAT_DEFAULT: segment.start = gst_util_uint64_scale_int (segment.start, GST_SECOND, self->rate); if (segment.stop != -1) segment.stop = gst_util_uint64_scale_int (segment.stop, GST_SECOND, self->rate); if (segment.position != -1) segment.position = gst_util_uint64_scale_int (segment.position, GST_SECOND, self->rate); break; default: GST_WARNING ("can't convert segment values"); segment.start = 0; segment.stop = -1; segment.position = 0; break; } event = gst_event_new_segment (&segment); } gst_pad_push_event (self->src, event); GST_OBJECT_LOCK (self); } GST_OBJECT_UNLOCK (self); if (timestamp != -1) { self->offset = gst_util_uint64_scale_int (timestamp, self->rate, GST_SECOND); self->timestamp = timestamp; } GST_BUFFER_TIMESTAMP (outbuf) = self->timestamp; GST_BUFFER_OFFSET (outbuf) = self->offset; self->offset += nsamples; self->timestamp = gst_util_uint64_scale_int (self->offset, GST_SECOND, self->rate); GST_BUFFER_DURATION (outbuf) = self->timestamp - GST_BUFFER_TIMESTAMP (outbuf); if (empty) GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP); gst_buffer_unmap (outbuf, &write_info); GST_LOG_OBJECT (self, "pushing outbuf, timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); ret = gst_pad_push (self->src, outbuf); return ret; eos: { GST_DEBUG_OBJECT (self, "no data available, must be EOS"); if (outbuf) gst_buffer_unref (outbuf); gst_pad_push_event (self->src, gst_event_new_eos ()); return GST_FLOW_EOS; } }
static void src_task_loop(GstPad *pad) { GstErDtlsEnc *self = GST_ER_DTLS_ENC(GST_PAD_PARENT(pad)); GstFlowReturn ret; GstPad *peer; gboolean peer_is_active; if (!gst_pad_is_active(pad)) { GST_LOG_OBJECT(self, "src task loop entered on inactive pad"); return; } GST_TRACE_OBJECT(self, "src loop: acquiring lock"); g_mutex_lock(&self->queue_lock); GST_TRACE_OBJECT(self, "src loop: acquired lock"); while (!self->queue->len) { GST_TRACE_OBJECT(self, "src loop: queue empty, waiting for add"); g_cond_wait(&self->queue_cond_add, &self->queue_lock); GST_TRACE_OBJECT(self, "src loop: add signaled"); if (!gst_pad_is_active(pad)) { GST_LOG_OBJECT(self, "pad inactive, task returning"); GST_TRACE_OBJECT(self, "src loop: releasing lock"); g_mutex_unlock(&self->queue_lock); return; } } GST_TRACE_OBJECT(self, "src loop: queue has element"); peer = gst_pad_get_peer(pad); peer_is_active = gst_pad_is_active(peer); gst_object_unref(peer); if (peer_is_active) { GstBuffer *buffer; gboolean start_connection_timeout = FALSE; if (self->send_initial_events) { GstSegment segment; gchar s_id[32]; GstCaps *caps; g_snprintf (s_id, sizeof (s_id), "erdtlsenc-%08x", g_random_int ()); gst_pad_push_event (self->src, gst_event_new_stream_start (s_id)); caps = gst_caps_new_empty_simple ("application/x-dtls"); gst_pad_push_event (self->src, gst_event_new_caps (caps)); gst_caps_unref (caps); gst_segment_init (&segment, GST_FORMAT_BYTES); gst_pad_push_event (self->src, gst_event_new_segment (&segment)); self->send_initial_events = FALSE; start_connection_timeout = TRUE; } buffer = g_ptr_array_remove_index(self->queue, 0); GST_TRACE_OBJECT(self, "src loop: releasing lock"); g_mutex_unlock(&self->queue_lock); ret = gst_pad_push(self->src, buffer); if (start_connection_timeout) er_dtls_connection_start_timeout (self->connection); if (G_UNLIKELY(ret != GST_FLOW_OK)) { GST_WARNING_OBJECT(self, "failed to push buffer on src pad: %s", gst_flow_get_name(ret)); } } else { g_warn_if_reached(); GST_TRACE_OBJECT(self, "src loop: releasing lock"); g_mutex_unlock(&self->queue_lock); } }
static void _create_issues (GstValidateRunner * runner) { GstPad *srcpad1, *srcpad2, *sinkpad, *funnel_sink1, *funnel_sink2; GstElement *src1, *src2, *sink, *fakemixer; GstSegment segment; src1 = create_and_monitor_element ("fakesrc2", "fakesrc1", runner); src2 = create_and_monitor_element ("fakesrc2", "fakesrc2", runner); fakemixer = create_and_monitor_element ("fakemixer", "fakemixer", runner); sink = create_and_monitor_element ("fakesink", "fakesink", runner); srcpad1 = gst_element_get_static_pad (src1, "src"); srcpad2 = gst_element_get_static_pad (src2, "src"); funnel_sink1 = gst_element_get_request_pad (fakemixer, "sink_%u"); funnel_sink2 = gst_element_get_request_pad (fakemixer, "sink_%u"); sinkpad = gst_element_get_static_pad (sink, "sink"); fail_unless (gst_element_link (fakemixer, sink)); fail_unless (gst_pad_link (srcpad1, funnel_sink1) == GST_PAD_LINK_OK); fail_unless (gst_pad_link (srcpad2, funnel_sink2) == GST_PAD_LINK_OK); /* We want to handle the src behaviour ourselves */ fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, TRUE)); fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, TRUE)); /* Setup all needed events */ gst_segment_init (&segment, GST_FORMAT_TIME); segment.start = 0; segment.stop = GST_SECOND; fail_unless (gst_pad_push_event (srcpad1, gst_event_new_stream_start ("the-stream"))); fail_unless (gst_pad_push_event (srcpad1, gst_event_new_segment (&segment))); fail_unless (gst_pad_push_event (srcpad2, gst_event_new_stream_start ("the-stream"))); fail_unless (gst_pad_push_event (srcpad2, gst_event_new_segment (&segment))); fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_PLAYING), GST_STATE_CHANGE_SUCCESS); fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_PLAYING), GST_STATE_CHANGE_ASYNC); /* Send an unexpected flush stop */ _gst_check_expecting_log = TRUE; fail_unless (gst_pad_push_event (srcpad1, gst_event_new_flush_stop (TRUE))); /* Once again but on the other fakemixer sink */ fail_unless (gst_pad_push_event (srcpad2, gst_event_new_flush_stop (TRUE))); /* clean up */ fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, FALSE)); fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, FALSE)); fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); gst_object_unref (srcpad1); gst_object_unref (srcpad2); gst_object_unref (sinkpad); gst_object_unref (funnel_sink1); gst_object_unref (funnel_sink2); gst_check_objects_destroyed_on_unref (fakemixer, funnel_sink1, funnel_sink2, NULL); gst_check_objects_destroyed_on_unref (src1, srcpad1, NULL); gst_check_objects_destroyed_on_unref (src2, srcpad2, NULL); gst_check_objects_destroyed_on_unref (sink, sinkpad, NULL); }
static void gst_srtp_dec_push_early_events (GstSrtpDec * filter, GstPad * pad, GstPad * otherpad, gboolean is_rtcp) { GstEvent *otherev, *ev; ev = gst_pad_get_sticky_event (pad, GST_EVENT_STREAM_START, 0); if (ev) { gst_event_unref (ev); } else { gchar *new_stream_id; otherev = gst_pad_get_sticky_event (otherpad, GST_EVENT_STREAM_START, 0); if (otherev) { const gchar *other_stream_id; gst_event_parse_stream_start (otherev, &other_stream_id); new_stream_id = g_strdup_printf ("%s/%s", other_stream_id, is_rtcp ? "rtcp" : "rtp"); gst_event_unref (otherev); } else { new_stream_id = gst_pad_create_stream_id (pad, GST_ELEMENT (filter), is_rtcp ? "rtcp" : "rtp"); } ev = gst_event_new_stream_start (new_stream_id); g_free (new_stream_id); gst_pad_push_event (pad, ev); } ev = gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0); if (ev) { gst_event_unref (ev); } else { GstCaps *caps; if (is_rtcp) caps = gst_caps_new_empty_simple ("application/x-rtcp"); else caps = gst_caps_new_empty_simple ("application/x-rtp"); gst_pad_set_caps (pad, caps); gst_caps_unref (caps); } ev = gst_pad_get_sticky_event (pad, GST_EVENT_SEGMENT, 0); if (ev) { gst_event_unref (ev); } else { ev = gst_pad_get_sticky_event (otherpad, GST_EVENT_SEGMENT, 0); if (ev) gst_pad_push_event (pad, ev); } if (is_rtcp) filter->rtcp_has_segment = TRUE; else filter->rtp_has_segment = TRUE; }
static GstMultipartPad * gst_multipart_find_pad_by_mime (GstMultipartDemux * demux, gchar * mime, gboolean * created) { GSList *walk; walk = demux->srcpads; while (walk) { GstMultipartPad *pad = (GstMultipartPad *) walk->data; if (!strcmp (pad->mime, mime)) { if (created) { *created = FALSE; } return pad; } walk = walk->next; } /* pad not found, create it */ { GstPad *pad; GstMultipartPad *mppad; gchar *name; const gchar *capsname; GstCaps *caps; gchar *stream_id; GstEvent *event; mppad = g_new0 (GstMultipartPad, 1); GST_DEBUG_OBJECT (demux, "creating pad with mime: %s", mime); name = g_strdup_printf ("src_%u", demux->numpads); pad = gst_pad_new_from_static_template (&multipart_demux_src_template_factory, name); g_free (name); mppad->pad = pad; mppad->mime = g_strdup (mime); mppad->last_ret = GST_FLOW_OK; mppad->last_ts = GST_CLOCK_TIME_NONE; mppad->discont = TRUE; demux->srcpads = g_slist_prepend (demux->srcpads, mppad); demux->numpads++; gst_pad_use_fixed_caps (pad); gst_pad_set_active (pad, TRUE); /* prepare and send stream-start */ if (!demux->have_group_id) { event = gst_pad_get_sticky_event (demux->sinkpad, GST_EVENT_STREAM_START, 0); if (event) { demux->have_group_id = gst_event_parse_group_id (event, &demux->group_id); gst_event_unref (event); } else if (!demux->have_group_id) { demux->have_group_id = TRUE; demux->group_id = gst_util_group_id_next (); } } stream_id = gst_pad_create_stream_id (pad, GST_ELEMENT_CAST (demux), demux->mime_type); event = gst_event_new_stream_start (stream_id); if (demux->have_group_id) gst_event_set_group_id (event, demux->group_id); gst_pad_store_sticky_event (pad, event); g_free (stream_id); gst_event_unref (event); /* take the mime type, convert it to the caps name */ capsname = gst_multipart_demux_get_gstname (demux, mime); caps = gst_caps_from_string (capsname); GST_DEBUG_OBJECT (demux, "caps for pad: %s", capsname); gst_pad_set_caps (pad, caps); gst_element_add_pad (GST_ELEMENT_CAST (demux), pad); gst_caps_unref (caps); if (created) { *created = TRUE; } if (demux->singleStream) { gst_element_no_more_pads (GST_ELEMENT_CAST (demux)); } return mppad; } }