Esempio n. 1
0
void
kms_element_for_each_src_pad (GstElement * element,
    KmsPadCallback action, gpointer data)
{
  GstIterator *it = gst_element_iterate_src_pads (element);
  gboolean done = FALSE;
  GstPad *pad;
  GValue item = G_VALUE_INIT;

  while (!done) {
    switch (gst_iterator_next (it, &item)) {
      case GST_ITERATOR_OK:
        pad = g_value_get_object (&item);
        action (pad, data);
        g_value_reset (&item);
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (it);
        break;
      case GST_ITERATOR_ERROR:
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
    }
  }

  g_value_unset (&item);
  gst_iterator_free (it);
}
Esempio n. 2
0
gboolean eos_callback(GstPad *pad,
                      GstObject *parent,
                      GstEvent *event)
{
    GstEvent *seek_event;
    GstElement *bkgdec;
    GValue v=G_VALUE_INIT;
    GstPad *srcpad;
    GstIterator *srcpads;
    gboolean result;

    g_print("Decodebin received EOS. Someone should handle that...\n");
    
    bkgdec=gst_pad_get_parent_element(pad);
    if(bkgdec->numsrcpads>0) {
        srcpads=gst_element_iterate_src_pads(bkgdec);
        gst_iterator_next(srcpads,&v);
        srcpad=GST_PAD(g_value_get_object(&v));
        seek_event=gst_event_new_seek ( 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
                         GST_SEEK_TYPE_SET, 0,
                         GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);     
        result=gst_pad_send_event(srcpad,seek_event);
        if(result==TRUE) {
            g_print("seek event sent OK.\n");
        } else {
           g_print("seek sent FAILED.\n");
        }
        g_value_reset(&v);
        g_value_unset(&v);
        gst_iterator_free(srcpads);
        return TRUE;
    }
    return gst_pad_event_default(pad,parent,event);
}
static void
gst_streamid_demux_reset (GstStreamidDemux * demux)
{
  GstIterator *it = NULL;
  GstIteratorResult itret = GST_ITERATOR_OK;

  GST_OBJECT_LOCK (demux);
  if (demux->active_srcpad != NULL)
    demux->active_srcpad = NULL;

  demux->nb_srcpads = 0;
  GST_OBJECT_UNLOCK (demux);

  if (demux->stream_id_pairs != NULL) {
    g_hash_table_unref (demux->stream_id_pairs);
    demux->stream_id_pairs = NULL;
  }

  it = gst_element_iterate_src_pads (GST_ELEMENT_CAST (demux));
  while (itret == GST_ITERATOR_OK || itret == GST_ITERATOR_RESYNC) {
    itret =
        gst_iterator_foreach (it,
        (GstIteratorForeachFunction) gst_streamid_demux_release_srcpad, demux);
    if (itret == GST_ITERATOR_RESYNC)
      gst_iterator_resync (it);
  }
  gst_iterator_free (it);
}
Esempio n. 4
0
void
kms_element_for_each_src_pad (GstElement * element,
    KmsPadCallback action, gpointer data)
{
  GstIterator *it = gst_element_iterate_src_pads (element);

  kms_element_iterate_pads (it, action, data);
  gst_iterator_free (it);
}
static void
gst_tee_pull_eos (GstTee * tee)
{
  GstIterator *iter;

  iter = gst_element_iterate_src_pads (GST_ELEMENT (tee));
  gst_iterator_foreach (iter, (GstIteratorForeachFunction) gst_tee_push_eos,
      tee);
  gst_iterator_free (iter);
}
static gboolean
disconnect_elements (GstElement * agnosticbin, GstElement * audiomixer)
{
  gboolean done = FALSE, disconnected = FALSE;
  GValue val = G_VALUE_INIT;
  GstIterator *it;

  it = gst_element_iterate_src_pads (agnosticbin);
  do {
    switch (gst_iterator_next (it, &val)) {
      case GST_ITERATOR_OK:
      {
        GstPad *srcpad, *sinkpad;
        GstElement *mixer;

        srcpad = g_value_get_object (&val);
        sinkpad = gst_pad_get_peer (srcpad);
        mixer = gst_pad_get_parent_element (sinkpad);

        if (mixer == audiomixer) {
          GST_DEBUG ("Unlink %" GST_PTR_FORMAT " and %" GST_PTR_FORMAT,
              agnosticbin, mixer);

          if (!gst_pad_unlink (srcpad, sinkpad)) {
            GST_ERROR ("Can not unlink %" GST_PTR_FORMAT " and %"
                GST_PTR_FORMAT, srcpad, sinkpad);
          }

          gst_element_release_request_pad (mixer, sinkpad);
          gst_element_release_request_pad (agnosticbin, srcpad);
          disconnected |= TRUE;
        }

        gst_object_unref (sinkpad);
        gst_object_unref (mixer);
        g_value_reset (&val);
        break;
      }
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (it);
        break;
      case GST_ITERATOR_ERROR:
        GST_ERROR ("Error iterating over %s's src pads",
            GST_ELEMENT_NAME (agnosticbin));
      case GST_ITERATOR_DONE:
        g_value_unset (&val);
        done = TRUE;
        break;
    }
  } while (!done);

  gst_iterator_free (it);

  return disconnected;
}
Esempio n. 7
0
///////////////////////////////////////////////////////////////////////////////////////////////////
/// gst_element_count_src_pads()
///
/// Count the element's src pads by using gst_element_iterate_src_pads.
///////////////////////////////////////////////////////////////////////////////////////////////////
gsize gst_element_count_src_pads(GstElement* element)
{
	GstIterator *iter = gst_element_iterate_src_pads(element);
	GValue vPad = G_VALUE_INIT;
	gsize ret = 0;
	while (gst_iterator_next(iter, &vPad) == GST_ITERATOR_OK)
	{
		ret++;
	}
	gst_iterator_free(iter);
	return ret;
} // END gst_element_count_src_pads()
Esempio n. 8
0
///////////////////////////////////////////////////////////////////////////////////////////////////
/// gst_element_get_first_src_pad()
///
/// Get an element's first source pad by using gst_element_iterate_sink_pads. The pad's ref count
/// is NOT incremented.
///////////////////////////////////////////////////////////////////////////////////////////////////
GstPad* gst_element_get_first_src_pad(GstElement* element)
{
	GstIterator *iter = gst_element_iterate_src_pads(element);
	GValue vPad = G_VALUE_INIT;
	GstPad* ret = NULL;
	if (gst_iterator_next(iter, &vPad) == GST_ITERATOR_OK)
	{
		ret = GST_PAD(g_value_get_object(&vPad));
	}
	gst_iterator_free(iter);
	return ret;
} // END gst_element_get_first_src_pad()
Esempio n. 9
0
static gboolean
kms_element_release_requested_srcpad_action (KmsElement * self,
    const gchar * pad_name)
{
  GValue item = G_VALUE_INIT;
  gboolean done = FALSE;
  gboolean released;
  GstIterator *it;
  GstPad *pad;

  KMS_ELEMENT_LOCK (self);
  released = g_hash_table_remove (self->priv->pendingpads, pad_name);
  KMS_ELEMENT_UNLOCK (self);

  if (released) {
    /* Pad was not created yet */
    return TRUE;
  }

  /* Pad is not in the pending list so it may have been already created */
  it = gst_element_iterate_src_pads (GST_ELEMENT (self));

  while (!done) {
    switch (gst_iterator_next (it, &item)) {
      case GST_ITERATOR_OK:{
        gchar *name;

        pad = g_value_get_object (&item);
        name = gst_pad_get_name (pad);
        if ((released = g_strcmp0 (name, pad_name) == 0)) {
          kms_element_remove_target_pad (self, pad);
          kms_element_release_pad (GST_ELEMENT (self), pad);
          done = TRUE;
        }
        g_value_reset (&item);
        g_free (name);
        break;
      }
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (it);
        break;
      case GST_ITERATOR_ERROR:
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
    }
  }

  gst_iterator_free (it);

  return released;
}
Esempio n. 10
0
static gboolean gst_sctp_dec_packet_event(GstPad *pad, GstSctpDec *self, GstEvent *event)
{
    switch (GST_EVENT_TYPE(event)) {
    case GST_EVENT_STREAM_START:
    case GST_EVENT_CAPS:
        /* We create our own stream-start events and the caps event does not
         * make sense */
        gst_event_unref(event);
        return TRUE;
    case GST_EVENT_EOS:
        /* Drop this, we're never EOS until shut down */
        gst_event_unref(event);
        return TRUE;
    case GST_EVENT_FLUSH_START: {
        GstIterator *it;

        it = gst_element_iterate_src_pads(GST_ELEMENT(self));
        while (gst_iterator_foreach(it, flush_srcpad, GINT_TO_POINTER(TRUE)) == GST_ITERATOR_RESYNC)
            gst_iterator_resync(it);
        gst_iterator_free(it);

        return gst_pad_event_default(pad, GST_OBJECT(self), event);
    }
    case GST_EVENT_FLUSH_STOP: {
        GstIterator *it;

        it = gst_element_iterate_src_pads(GST_ELEMENT(self));
        while (gst_iterator_foreach(it, flush_srcpad, GINT_TO_POINTER(FALSE)) == GST_ITERATOR_RESYNC)
            gst_iterator_resync(it);
        gst_iterator_free(it);

        return gst_pad_event_default(pad, GST_OBJECT(self), event);
    }
    default:
        return gst_pad_event_default(pad, GST_OBJECT(self), event);
    }
}
Esempio n. 11
0
///////////////////////////////////////////////////////////////////////////////////////////////////
/// gst_element_find_src_pad_by_name()
///
/// Find an element's src pad by name by using gst_element_iterate_src_pads and comparing the
/// element's name with that provided.
///////////////////////////////////////////////////////////////////////////////////////////////////
GstPad* gst_element_find_src_pad_by_name(GstElement* element, const gchar* name)
{
	GstIterator *iter = gst_element_iterate_src_pads(element);
	GValue vPad = G_VALUE_INIT;
	GstPad* ret = NULL;
	while (gst_iterator_next(iter, &vPad) == GST_ITERATOR_OK)
	{
		GstPad* pad = GST_PAD(g_value_get_object(&vPad));
		const gchar* pad_name = gst_pad_get_name(pad);
		if (g_strcmp0(pad_name, name) == 0)
		{
			ret = pad;
		}
		g_free(const_cast<gchar*>(pad_name));
		if (ret != NULL)
		{
			break;
		}
	}
	gst_iterator_free(iter);
	return ret;
} // END gst_element_find_src_pad_by_name()
static gboolean
_gst_context_run_query (GstElement * element, GstQuery * query,
    GstPadDirection direction)
{
  GstIteratorFoldFunction const func = context_pad_query;
  GstIterator *it;
  GValue res = { 0 };

  g_value_init (&res, G_TYPE_BOOLEAN);
  g_value_set_boolean (&res, FALSE);

  /* Ask neighbour */
  if (direction == GST_PAD_SRC)
    it = gst_element_iterate_src_pads (element);
  else
    it = gst_element_iterate_sink_pads (element);

  while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC)
    gst_iterator_resync (it);
  gst_iterator_free (it);

  return g_value_get_boolean (&res);
}
Esempio n. 13
0
static void
request_pad_unlinked_cb(GstPad *pad, GstPad *peer, gpointer user_data)
{
	GstElement *parent = GST_ELEMENT_PARENT(pad);
	GstIterator *iter;
	GstPad *remaining_pad;
	GstIteratorResult result;

	gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad);
	iter = gst_element_iterate_src_pads(parent);

	result = gst_iterator_next(iter, (gpointer)&remaining_pad);

	if (result == GST_ITERATOR_DONE) {
		gst_element_set_locked_state(parent, TRUE);
		gst_element_set_state(parent, GST_STATE_NULL);
		gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(parent)), parent);
	} else if (result == GST_ITERATOR_OK) {
		gst_object_unref(remaining_pad);
	}

	gst_iterator_free(iter);
}
Esempio n. 14
0
static GstIterator *
gst_rtp_ssrc_demux_iterate_internal_links_sink (GstPad * pad,
        GstObject * parent)
{
    GstRtpSsrcDemux *demux;
    GstIterator *it = NULL;
    GValue gval = { 0, };

    demux = GST_RTP_SSRC_DEMUX (parent);

    g_value_init (&gval, G_TYPE_STRING);
    if (pad == demux->rtp_sink)
        g_value_set_static_string (&gval, "src_");
    else if (pad == demux->rtcp_sink)
        g_value_set_static_string (&gval, "rtcp_src_");
    else
        g_assert_not_reached ();

    it = gst_element_iterate_src_pads (GST_ELEMENT_CAST (demux));
    it = gst_iterator_filter (it, src_pad_compare_func, &gval);

    return it;
}
Esempio n. 15
0
static HRESULT WINAPI Gstreamer_YUV_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir,  const AM_MEDIA_TYPE *amt) {
    GstTfImpl *This = (GstTfImpl*)tf;
    GstCaps *capsin, *capsout;
    AM_MEDIA_TYPE *outpmt = &This->tf.pmt;
    HRESULT hr;
    int avgtime;
    LONG width, height;

    if (dir != PINDIR_INPUT)
        return S_OK;

    if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
        return E_FAIL;

    FreeMediaType(outpmt);
    CopyMediaType(outpmt, amt);

    if (IsEqualGUID(&amt->formattype, &FORMAT_VideoInfo)) {
        VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)outpmt->pbFormat;
        avgtime = vih->AvgTimePerFrame;
        width = vih->bmiHeader.biWidth;
        height = vih->bmiHeader.biHeight;
        if (vih->bmiHeader.biHeight > 0)
            vih->bmiHeader.biHeight = -vih->bmiHeader.biHeight;
        vih->bmiHeader.biBitCount = 24;
        vih->bmiHeader.biCompression = BI_RGB;
        vih->bmiHeader.biSizeImage = width * abs(height) * 3;
    } else {
        VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)outpmt->pbFormat;
        avgtime = vih->AvgTimePerFrame;
        width = vih->bmiHeader.biWidth;
        height = vih->bmiHeader.biHeight;
        if (vih->bmiHeader.biHeight > 0)
            vih->bmiHeader.biHeight = -vih->bmiHeader.biHeight;
        vih->bmiHeader.biBitCount = 24;
        vih->bmiHeader.biCompression = BI_RGB;
        vih->bmiHeader.biSizeImage = width * abs(height) * 3;
    }
    if (!avgtime)
        avgtime = 10000000 / 30;

    outpmt->subtype = MEDIASUBTYPE_RGB24;

    capsin = gst_caps_new_simple("video/x-raw-yuv",
                                 "format", GST_TYPE_FOURCC, amt->subtype.Data1,
                                 "width", G_TYPE_INT, width,
                                 "height", G_TYPE_INT, height,
                                 "framerate", GST_TYPE_FRACTION, 10000000, (int)avgtime,
                                 NULL);
    capsout = gst_caps_new_simple("video/x-raw-rgb",
                                  "bpp", G_TYPE_INT, 24,
                                  "depth", G_TYPE_INT, 24,
                                  "endianness", G_TYPE_INT, 4321,
                                  "red_mask", G_TYPE_INT, 0xff,
                                  "green_mask", G_TYPE_INT, 0xff00,
                                  "blue_mask", G_TYPE_INT, 0xff0000,
                                  "width", G_TYPE_INT, width,
                                  "height", G_TYPE_INT, height,
                                  "framerate", GST_TYPE_FRACTION, 10000000, (int)avgtime,
                                   NULL);

    This->filter2 = gst_element_factory_make("videoflip", NULL);
    if (This->filter2) {
        GstIterator *it;
        int done = 0;

        g_object_set(This->filter2, "method", 5, NULL);

        it = gst_element_iterate_sink_pads(This->filter2);
        while (!done) {
            gpointer item;

            switch (gst_iterator_next(it, &item)) {
            case GST_ITERATOR_RESYNC:
                gst_iterator_resync (it);
                break;
            case GST_ITERATOR_OK:
                This->their_sink2 = item;
            case GST_ITERATOR_ERROR:
            case GST_ITERATOR_DONE:
                done = 1;
                break;
            }
        }
        gst_iterator_free(it);

        done = 0;
        it = gst_element_iterate_src_pads(This->filter2);
        while (!done) {
            gpointer item;

            switch (gst_iterator_next(it, &item)) {
            case GST_ITERATOR_RESYNC:
                gst_iterator_resync (it);
                break;
            case GST_ITERATOR_OK:
                This->their_src2 = item;
            case GST_ITERATOR_ERROR:
            case GST_ITERATOR_DONE:
                done = 1;
                break;
            }
        }
        gst_iterator_free(it);

        if (!This->their_src2 || !This->their_sink2) {
            if (This->their_src2)
                gst_object_unref(This->their_src2);
            if (This->their_sink2)
                gst_object_unref(This->their_sink2);
            gst_object_unref(This->filter2);
            This->filter2 = 0;
        }
    }

    hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout);
    gst_caps_unref(capsin);
    gst_caps_unref(capsout);

    This->cbBuffer = width * height * 4;
    return hr;
}
Esempio n. 16
0
    void RTSPserverGate::setLocation(std::string a)
	{

	if (factory->key)
	    {

	    if (!lock_transition && pid == 0)
		{
		lock_transition = true;
		this->location = a;
		GstStateChangeReturn ret;
		GstPad *pad;
		GstState state;
		GstState rtspstate;
		gchar *key;
		GstRTSPMedia *media;
		GstRTSPMediaFactoryClass *klass;
		GstElement * source;
		GstElement * buffer;
		std::clog << "Key:" << factory->key << std::endl;
		klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS(this->factory);
		g_mutex_lock(this->factory->medias_lock);
		media = static_cast<GstRTSPMedia*> (g_hash_table_lookup(
			factory->medias, factory->key));

		if (media)
		    g_object_ref(media);

		if (media)
		    {
		    source = gst_bin_get_by_name(GST_BIN(media->element),
			    "gate");
		    if (source)
			{
			std::clog << "########## address:" << std::endl;

			GstIterator* it = gst_element_iterate_src_pads(source);
			GstIteratorResult result = GST_ITERATOR_OK;
			if (result == GST_ITERATOR_OK)
			    {
			    gpointer p;
			    result = gst_iterator_next(it, &p);
			    GstPad* pad = GST_PAD(p);
			    std::clog << "PadName: " << gst_pad_get_name(pad)
				    << std::endl;
			    gst_pad_set_blocked_async(pad, TRUE,
				    gate_block_async_cb, this);
			    //g_object_unref(pad);
			    }
			gst_iterator_free(it);

			}
		    g_mutex_unlock(this->factory->medias_lock);
		    g_object_unref(media);

		    }
		}

	    }

	else
	    {
	    this->location = a;
	    this->pipeline
		    = "( rtspsrc location=" + this->location
			    + " latency=1  name=gate ! rtph264depay name=buffer byte-stream=false  ! queue2 max-size-bytes=100000000 use-buffering=true ! rtph264pay name=pay0 pt=96 )";



	    }
	}
Esempio n. 17
0
static HRESULT Gstreamer_transform_ConnectInput(GstTfImpl *This, const AM_MEDIA_TYPE *amt, GstCaps *capsin, GstCaps *capsout)
{
    GstIterator *it;
    BOOL done = FALSE, found = FALSE;
    int ret;

    TRACE("%p %p %p %p\n", This, amt, capsin, capsout);

    mark_wine_thread();

    This->filter = gst_element_factory_make(This->gstreamer_name, NULL);
    if (!This->filter) {
        FIXME("Could not make %s filter\n", This->gstreamer_name);
        return E_FAIL;
    }
    This->my_src = gst_pad_new("yuvsrc", GST_PAD_SRC);
    gst_pad_set_element_private (This->my_src, This);
    gst_pad_set_active(This->my_src, 1);

    This->my_sink = gst_pad_new("yuvsink", GST_PAD_SINK);
    gst_pad_set_chain_function(This->my_sink, got_data_wrapper);
    gst_pad_set_element_private (This->my_sink, This);
    gst_pad_set_active(This->my_sink, 1);

    it = gst_element_iterate_sink_pads(This->filter);
    while (!done) {
        GValue item = {0};

        switch (gst_iterator_next(it, &item)) {
        case GST_ITERATOR_RESYNC:
            gst_iterator_resync (it);
            break;
        case GST_ITERATOR_OK:
            This->their_sink = g_value_get_object(&item);
            gst_object_ref(This->their_sink);
            g_value_reset(&item);
        case GST_ITERATOR_ERROR:
        case GST_ITERATOR_DONE:
            done = TRUE;
            break;
        }
    }
    gst_iterator_free(it);
    if (!This->their_sink) {
        ERR("Could not find sink on filter %s\n", This->gstreamer_name);
        return E_FAIL;
    }

    it = gst_element_iterate_src_pads(This->filter);
    gst_iterator_resync(it);
    done = FALSE;
    while (!done) {
        GValue item = {0};

        switch (gst_iterator_next(it, &item)) {
        case GST_ITERATOR_RESYNC:
            gst_iterator_resync (it);
            break;
        case GST_ITERATOR_OK:
            This->their_src = g_value_get_object(&item);
            gst_object_ref(This->their_src);
            g_value_reset(&item);
        case GST_ITERATOR_ERROR:
        case GST_ITERATOR_DONE:
            done = TRUE;
            break;
        }
    }
    gst_iterator_free(it);
    found = !!This->their_src;
    if (!found)
        g_signal_connect(This->filter, "pad-added", G_CALLBACK(Gstreamer_transform_pad_added_wrapper), This);
    ret = gst_pad_link(This->my_src, This->their_sink);
    if (ret < 0) {
        WARN("Failed to link with %i\n", ret);
        return E_FAIL;
    }

    ret = gst_pad_set_caps(This->my_src, capsin);
    if (ret < 0) {
        WARN("Failed to set caps on own source with %i\n", ret);
        return E_FAIL;
    }

    if (found)
        Gstreamer_transform_pad_added(This->filter, This->their_src, This);

    if (!gst_pad_is_linked(This->my_sink))
        return E_FAIL;

    ret = gst_pad_set_caps(This->my_sink, capsout);
    if (ret < 0) {
        WARN("Failed to set caps on own sink with %i\n", ret);
        return E_FAIL;
    }

    TRACE("Connected\n");
    return S_OK;
}
Esempio n. 18
0
static HRESULT Gstreamer_transform_ConnectInput(GstTfImpl *This, const AM_MEDIA_TYPE *amt, GstCaps *capsin, GstCaps *capsout) {
    GstIterator *it;
    int done = 0, found = 0, ret;

    This->filter = gst_element_factory_make(This->gstreamer_name, NULL);
    if (!This->filter) {
        FIXME("Could not make %s filter\n", This->gstreamer_name);
        return E_FAIL;
    }
    This->my_src = gst_pad_new(NULL, GST_PAD_SRC);
    gst_pad_set_element_private (This->my_src, This);

    This->my_sink = gst_pad_new(NULL, GST_PAD_SINK);
    gst_pad_set_chain_function(This->my_sink, got_data);
    gst_pad_set_bufferalloc_function(This->my_sink, request_buffer);
    gst_pad_set_element_private (This->my_sink, This);

    ret = gst_pad_set_caps(This->my_src, capsin);
    if (ret < 0) {
        WARN("Failed to set caps on own source with %i\n", ret);
        return E_FAIL;
    }

    ret = gst_pad_set_caps(This->my_sink, capsout);
    if (ret < 0) {
        WARN("Failed to set caps on own sink with %i\n", ret);
        return E_FAIL;
    }

    it = gst_element_iterate_sink_pads(This->filter);
    while (!done) {
        gpointer item;

        switch (gst_iterator_next(it, &item)) {
        case GST_ITERATOR_RESYNC:
            gst_iterator_resync (it);
            break;
        case GST_ITERATOR_OK:
            This->their_sink = item;
        case GST_ITERATOR_ERROR:
        case GST_ITERATOR_DONE:
            done = 1;
            break;
        }
    }
    gst_iterator_free(it);
    if (!This->their_sink) {
        ERR("Could not find sink on filter %s\n", This->gstreamer_name);
        return E_FAIL;
    }

    it = gst_element_iterate_src_pads(This->filter);
    gst_iterator_resync(it);
    done = 0;
    while (!done) {
        gpointer item;

        switch (gst_iterator_next(it, &item)) {
        case GST_ITERATOR_RESYNC:
            gst_iterator_resync (it);
            break;
        case GST_ITERATOR_OK:
            This->their_src = item;
        case GST_ITERATOR_ERROR:
        case GST_ITERATOR_DONE:
            done = 1;
            break;
        }
    }
    gst_iterator_free(it);
    found = !!This->their_src;
    if (!found)
        g_signal_connect(This->filter, "pad-added", G_CALLBACK(Gstreamer_transform_pad_added), This);
    ret = gst_pad_link(This->my_src, This->their_sink);
    if (ret < 0) {
        WARN("Failed to link with %i\n", ret);
        return E_FAIL;
    }

    if (found)
        Gstreamer_transform_pad_added(This->filter, This->their_src, This);

    if (!gst_pad_is_linked(This->my_sink))
        return E_FAIL;

    TRACE("Connected\n");
    return S_OK;
}
Esempio n. 19
0
gint
main (gint argc, gchar * argv[])
{
  GstElement *pipeline, *filesrc, *decodebin;
  GstStateChangeReturn res;
  GstIterator *it;
  GstBus *bus;
  GValue data = { 0, };

  gst_init (&argc, &argv);

  pipeline = gst_pipeline_new ("pipeline");

  filesrc = gst_element_factory_make ("filesrc", "filesrc");
  g_assert (filesrc);

  decodebin = gst_element_factory_make ("decodebin", "decodebin");
  g_assert (decodebin);

  gst_bin_add_many (GST_BIN (pipeline), filesrc, decodebin, NULL);
  gst_element_link (filesrc, decodebin);

  if (argc < 2) {
    g_print ("usage: %s <filenames>\n", argv[0]);
    exit (-1);
  }

  if (!g_str_has_prefix (argv[1], "file://")) {
    g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
  } else {
    g_object_set (G_OBJECT (filesrc), "location", argv[1] + 7, NULL);
  }

  /* we've got to connect fakesinks to newly decoded pads to make sure
   * buffers have actually been flowing over those pads and caps have
   * been set on them. decodebin might insert internal queues and
   * without fakesinks it's pot-luck what caps we get from the pad, because
   * it depends on whether the queues have started pushing buffers yet or not.
   * With fakesinks we make sure that the pipeline doesn't go to PAUSED state
   * before each fakesink has a buffer queued. */
  g_signal_connect (decodebin, "new-decoded-pad",
      G_CALLBACK (new_decoded_pad_cb), pipeline);

  bus = gst_element_get_bus (pipeline);

  g_print ("pause..\n");
  res = gst_element_set_state (pipeline, GST_STATE_PAUSED);
  if (res == GST_STATE_CHANGE_FAILURE) {
    show_error ("Could not go to PAUSED state", bus);
    exit (-1);
  }
  g_print ("waiting..\n");
  res = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
  if (res != GST_STATE_CHANGE_SUCCESS) {
    show_error ("Failed to complete state change to PAUSED", bus);
    exit (-1);
  }
  g_print ("stats..\n");

  it = gst_element_iterate_src_pads (decodebin);
  while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) {
    GstPad *pad = g_value_get_object (&data);
    GstCaps *caps;
    gchar *str;
    GstQuery *query;

    g_print ("stream %s:\n", GST_OBJECT_NAME (pad));

    caps = gst_pad_query_caps (pad, NULL);
    str = gst_caps_to_string (caps);
    g_print (" caps: %s\n", str);
    g_free (str);
    gst_caps_unref (caps);

    query = gst_query_new_duration (GST_FORMAT_TIME);
    if (gst_pad_query (pad, query)) {
      gint64 duration;

      gst_query_parse_duration (query, NULL, &duration);

      g_print (" duration: %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (duration));
    }
    gst_query_unref (query);

    g_value_reset (&data);
  }
  g_value_unset (&data);
  gst_iterator_free (it);

  return 0;
}
static gboolean
validate_codec_profile (FsCodec *codec,const gchar *bin_description,
    gboolean is_send)
{
  GError *error = NULL;
  GstElement *bin = NULL;
  guint src_pad_count = 0, sink_pad_count = 0;
  GstCaps *caps;
  gpointer matching_pad = NULL;
  GstIterator *iter;

  bin = parse_bin_from_description_all_linked (bin_description,
      &src_pad_count, &sink_pad_count, &error);

  /* if could not build bin, fail */
  if (!bin)
  {
    GST_WARNING ("Could not build profile (%s): %s", bin_description,
        error->message);
    g_clear_error (&error);
    return FALSE;
  }
  g_clear_error (&error);

  caps = fs_codec_to_gst_caps (codec);

  if (is_send)
    iter = gst_element_iterate_src_pads (bin);
  else
    iter = gst_element_iterate_sink_pads (bin);

  matching_pad = gst_iterator_find_custom (iter, find_matching_pad, caps);
  gst_iterator_free (iter);

  if (!matching_pad)
  {
    GST_WARNING ("Invalid profile (%s), has no %s pad that matches the codec"
        " details", is_send ? "src" : "sink", bin_description);
    gst_caps_unref (caps);
    gst_object_unref (bin);
    return FALSE;
  }

  gst_caps_unref (caps);
  gst_object_unref (bin);

  if (is_send)
  {
    if (src_pad_count == 0)
    {
      GST_WARNING ("Invalid profile (%s), has 0 src pad", bin_description);
      return FALSE;
    }
  }
  else
  {
    if (src_pad_count != 1)
    {
      GST_WARNING ("Invalid profile (%s), has %u src pads, should have one",
          bin_description, src_pad_count);
      return FALSE;
    }
  }

  if (sink_pad_count != 1)
  {
    GST_WARNING ("Invalid profile (%s), has %u sink pads, should have one",
        bin_description, sink_pad_count);
    return FALSE;
  }

  return TRUE;
}
/*
 * debug_dump_element:
 * @bin: the bin that should be analyzed
 * @out: file to write to
 * @indent: level of graph indentation
 *
 * Helper for gst_debug_bin_to_dot_file() to recursively dump a pipeline.
 */
static void
debug_dump_element (GstBin * bin, GstDebugGraphDetails details,
    GString * str, const gint indent)
{
  GstIterator *element_iter, *pad_iter;
  gboolean elements_done, pads_done;
  GValue item = { 0, };
  GValue item2 = { 0, };
  GstElement *element;
  GstPad *pad = NULL;
  guint src_pads, sink_pads;
  gchar *element_name;
  gchar *state_name = NULL;
  gchar *param_name = NULL;
  const gchar *spc = &spaces[MAX (sizeof (spaces) - (1 + indent * 2), 0)];

  element_iter = gst_bin_iterate_elements (bin);
  elements_done = FALSE;
  while (!elements_done) {
    switch (gst_iterator_next (element_iter, &item)) {
      case GST_ITERATOR_OK:
        element = g_value_get_object (&item);
        element_name = debug_dump_make_object_name (GST_OBJECT (element));

        if (details & GST_DEBUG_GRAPH_SHOW_STATES) {
          state_name = debug_dump_get_element_state (GST_ELEMENT (element));
        }
        if (details & GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS) {
          param_name = debug_dump_get_element_params (GST_ELEMENT (element),
              details);
        }
        /* elements */
        g_string_append_printf (str, "%ssubgraph cluster_%s {\n", spc,
            element_name);
        g_string_append_printf (str, "%s  fontname=\"Bitstream Vera Sans\";\n",
            spc);
        g_string_append_printf (str, "%s  fontsize=\"8\";\n", spc);
        g_string_append_printf (str, "%s  style=filled;\n", spc);
        g_string_append_printf (str, "%s  color=black;\n\n", spc);
        g_string_append_printf (str, "%s  label=\"%s\\n%s%s%s\";\n", spc,
            G_OBJECT_TYPE_NAME (element), GST_OBJECT_NAME (element),
            (state_name ? state_name : ""), (param_name ? param_name : "")
            );
        if (state_name) {
          g_free (state_name);
          state_name = NULL;
        }
        if (param_name) {
          g_free (param_name);
          param_name = NULL;
        }
        g_free (element_name);

        src_pads = sink_pads = 0;
        if ((pad_iter = gst_element_iterate_sink_pads (element))) {
          debug_dump_element_pads (pad_iter, pad, element, details, str,
              indent, &src_pads, &sink_pads);
          gst_iterator_free (pad_iter);
        }
        if ((pad_iter = gst_element_iterate_src_pads (element))) {
          debug_dump_element_pads (pad_iter, pad, element, details, str,
              indent, &src_pads, &sink_pads);
          gst_iterator_free (pad_iter);
        }
        if (GST_IS_BIN (element)) {
          g_string_append_printf (str, "%s  fillcolor=\"#ffffff\";\n", spc);
          /* recurse */
          debug_dump_element (GST_BIN (element), details, str, indent + 1);
        } else {
          if (src_pads && !sink_pads)
            g_string_append_printf (str, "%s  fillcolor=\"#ffaaaa\";\n", spc);
          else if (!src_pads && sink_pads)
            g_string_append_printf (str, "%s  fillcolor=\"#aaaaff\";\n", spc);
          else if (src_pads && sink_pads)
            g_string_append_printf (str, "%s  fillcolor=\"#aaffaa\";\n", spc);
          else
            g_string_append_printf (str, "%s  fillcolor=\"#ffffff\";\n", spc);
        }
        g_string_append_printf (str, "%s}\n\n", spc);
        if ((pad_iter = gst_element_iterate_pads (element))) {
          pads_done = FALSE;
          while (!pads_done) {
            switch (gst_iterator_next (pad_iter, &item2)) {
              case GST_ITERATOR_OK:
                pad = g_value_get_object (&item2);
                if (gst_pad_is_linked (pad)) {
                  if (gst_pad_get_direction (pad) == GST_PAD_SRC) {
                    debug_dump_element_pad_link (pad, element, details, str,
                        indent);
                  } else {
                    GstPad *peer_pad = gst_pad_get_peer (pad);

                    if (peer_pad) {
                      if (!GST_IS_GHOST_PAD (peer_pad)
                          && GST_IS_PROXY_PAD (peer_pad)) {
                        debug_dump_element_pad_link (peer_pad, NULL, details,
                            str, indent);
                      }
                      gst_object_unref (peer_pad);
                    }
                  }
                }
                g_value_reset (&item2);
                break;
              case GST_ITERATOR_RESYNC:
                gst_iterator_resync (pad_iter);
                break;
              case GST_ITERATOR_ERROR:
              case GST_ITERATOR_DONE:
                pads_done = TRUE;
                break;
            }
          }
          g_value_unset (&item2);
          gst_iterator_free (pad_iter);
        }
        g_value_reset (&item);
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (element_iter);
        break;
      case GST_ITERATOR_ERROR:
      case GST_ITERATOR_DONE:
        elements_done = TRUE;
        break;
    }
  }

  g_value_unset (&item);
  gst_iterator_free (element_iter);
}
/* Fetches a compatible pad on the target element which isn't already
 * linked */
static GstPad *
get_compatible_unlinked_pad (GstElement * element, GstPad * pad)
{
  GstPad *res = NULL;
  GstIterator *pads;
  gboolean done = FALSE;
  GstCaps *srccaps;

  if (G_UNLIKELY (pad == NULL))
    goto no_pad;

  GST_DEBUG ("element : %s, pad %s:%s",
      GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad));

  if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
    pads = gst_element_iterate_sink_pads (element);
  else
    pads = gst_element_iterate_src_pads (element);
  srccaps = gst_pad_get_caps_reffed (pad);

  GST_DEBUG ("srccaps %" GST_PTR_FORMAT, srccaps);

  while (!done) {
    gpointer padptr;

    switch (gst_iterator_next (pads, &padptr)) {
      case GST_ITERATOR_OK:
      {
        GstPad *testpad = (GstPad *) padptr;

        if (gst_pad_is_linked (testpad)) {
          gst_object_unref (testpad);
        } else {
          GstCaps *sinkcaps = gst_pad_get_caps_reffed (testpad);

          GST_DEBUG ("sinkccaps %" GST_PTR_FORMAT, sinkcaps);

          if (gst_caps_can_intersect (srccaps, sinkcaps)) {
            res = testpad;
            done = TRUE;
          } else
            gst_object_unref (testpad);
          gst_caps_unref (sinkcaps);
        }
      }
        break;
      case GST_ITERATOR_DONE:
      case GST_ITERATOR_ERROR:
        done = TRUE;
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (pads);
        break;
    }
  }
  gst_iterator_free (pads);
  gst_caps_unref (srccaps);

  return res;

no_pad:
  {
    GST_ERROR ("No pad to check against");
    return NULL;
  }
}