Exemple #1
0
static GstPadLinkReturn
gst_frame_store_link_src (GstPad *pad, GstPad *peer)
{
  GstPadLinkReturn result = GST_PAD_LINK_OK;
  GstFrameStore *fs;
  
  fs = GST_FRAME_STORE(gst_pad_get_parent(pad));

  if (GST_PAD_LINKFUNC (peer)) {
    result = GST_PAD_LINKFUNC(peer) (peer, pad);
  }

  if (GST_PAD_LINK_SUCCESSFUL (result)) {
    g_mutex_lock (fs->lock);
    
fs->srcresult = GST_FLOW_OK;
    if (fs->srcresult == GST_FLOW_OK) {
      gst_pad_start_task (pad, (GstTaskFunction) gst_frame_store_task,
          pad);
    } else {
      GST_DEBUG("not starting task");
      /* not starting task */
    }
    g_mutex_unlock (fs->lock);
  }

  gst_object_unref (fs);

  return result;
}
Exemple #2
0
static void
src_pad_added_cb (FsStream *stream, GstPad *pad, FsCodec *codec,
    gpointer user_data)
{
  GstElement *pipeline = GST_ELEMENT_CAST (user_data);
  GstElement *sink = NULL;
  GError *error = NULL;
  GstPad *pad2;

  g_print ("Adding receive pipeline\n");

  if (g_getenv ("AUDIOSINK"))
    sink = gst_parse_bin_from_description (g_getenv ("AUDIOSINK"), TRUE,
        &error);
  else
    sink = gst_parse_bin_from_description (DEFAULT_AUDIOSINK, TRUE,
        &error);
  print_error (error);
  g_assert (sink);

  g_assert (gst_bin_add (GST_BIN (pipeline), sink));


  pad2 = gst_element_get_static_pad (sink, "sink");
  g_assert (pad2);

  g_assert (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (pad, pad2)));

  g_assert (gst_element_set_state (sink, GST_STATE_PLAYING) !=
      GST_STATE_CHANGE_FAILURE);

  gst_object_unref (pad2);
}
Exemple #3
0
void
MediaParserGst::link_to_fakesink(GstPad* pad)
{
    GstElement* fakesink = gst_element_factory_make("fakesink", NULL);
    
    if (!fakesink) {
        throw MediaException(_("MediaParserGst Failed to create fakesink."));
    }

    gboolean success = gst_bin_add(GST_BIN(_bin), fakesink);
    
    if (!success) {
        gst_object_unref(fakesink);
        throw MediaException(_("MediaParserGst Failed to create fakesink."));
    }
    
    GstPad* sinkpad = gst_element_get_static_pad (fakesink, "sink");
    if (!sinkpad) {
        gst_object_unref(fakesink);
        throw MediaException(_("MediaParserGst: couldn't get the fakesink "
                               "src element."));
    }
    
    GstPadLinkReturn ret = gst_pad_link(pad, sinkpad);
    if (!GST_PAD_LINK_SUCCESSFUL(ret)) {
        gst_object_unref(fakesink);
        gst_object_unref(sinkpad);
        throw MediaException(_("MediaParserGst: couln't link fakesink"));
    }
    
    if (!gst_element_set_state (_bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS) {
        throw GnashException(_("MediaParserGst could not change element state"));
    }
}
Exemple #4
0
static void
gst_mikmod_loop (GstElement * element)
{
  GstMikMod *mikmod;
  GstBuffer *buffer_in;

  g_return_if_fail (element != NULL);
  g_return_if_fail (GST_IS_MIKMOD (element));

  mikmod = GST_MIKMOD (element);
  srcpad = mikmod->srcpad;
  mikmod->Buffer = NULL;

  if (!mikmod->initialized) {
    while ((buffer_in = GST_BUFFER (gst_pad_pull (mikmod->sinkpad)))) {
      if (GST_IS_EVENT (buffer_in)) {
        GstEvent *event = GST_EVENT (buffer_in);

        if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
          break;
      } else {
        if (mikmod->Buffer) {
          mikmod->Buffer = gst_buffer_append (mikmod->Buffer, buffer_in);
        } else {
          mikmod->Buffer = buffer_in;
        }
      }
    }

    if (!GST_PAD_CAPS (mikmod->srcpad)) {
      if (GST_PAD_LINK_SUCCESSFUL (gst_pad_renegotiate (mikmod->srcpad))) {
        GST_ELEMENT_ERROR (mikmod, CORE, NEGOTIATION, (NULL), (NULL));
        return;
      }
    }

    MikMod_RegisterDriver (&drv_gst);
    MikMod_RegisterAllLoaders ();

    MikMod_Init ("");
    reader = GST_READER_new (mikmod);
    module = Player_LoadGeneric (reader, 64, 0);

    gst_buffer_unref (mikmod->Buffer);

    if (!Player_Active ())
      Player_Start (module);

    mikmod->initialized = TRUE;
  }

  if (Player_Active ()) {
    timestamp = (module->sngtime / 1024.0) * GST_SECOND;
    drv_gst.Update ();
  } else {
    gst_element_set_eos (GST_ELEMENT (mikmod));
    gst_pad_push (mikmod->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
  }
}
Exemple #5
0
static void
setup_test_objects (struct TestData *td, GstPadChainFunction chain_func, GstPadBufferAllocFunction alloc_func)
{
  td->mycaps = gst_caps_new_simple ("test/test", NULL);

  td->funnel = gst_element_factory_make ("fsfunnel", NULL);

  td->funnelsrc = gst_element_get_static_pad (td->funnel, "src");
  fail_unless (td->funnelsrc != NULL);

  td->funnelsink11 = gst_element_get_request_pad (td->funnel, "sink11");
  fail_unless (td->funnelsink11 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink11), "sink11"));

  td->funnelsink22 = gst_element_get_request_pad (td->funnel, "sink22");
  fail_unless (td->funnelsink22 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink22), "sink22"));

  fail_unless (gst_element_set_state (td->funnel, GST_STATE_PLAYING) ==
      GST_STATE_CHANGE_SUCCESS);

  td->mysink = gst_pad_new ("sink", GST_PAD_SINK);
  gst_pad_set_chain_function (td->mysink, chain_func);
  gst_pad_set_bufferalloc_function (td->mysink, alloc_func);
  gst_pad_set_active (td->mysink, TRUE);
  gst_pad_set_caps (td->mysink, td->mycaps);

  td->mysrc1 = gst_pad_new ("src1", GST_PAD_SRC);
  gst_pad_set_active (td->mysrc1, TRUE);
  gst_pad_set_caps (td->mysrc1, td->mycaps);

  td->mysrc2 = gst_pad_new ("src2", GST_PAD_SRC);
  gst_pad_set_active (td->mysrc2, TRUE);
  gst_pad_set_caps (td->mysrc2, td->mycaps);

  fail_unless (GST_PAD_LINK_SUCCESSFUL(
          gst_pad_link (td->funnelsrc, td->mysink)));

  fail_unless (GST_PAD_LINK_SUCCESSFUL(
          gst_pad_link (td->mysrc1, td->funnelsink11)));

  fail_unless (GST_PAD_LINK_SUCCESSFUL(
          gst_pad_link (td->mysrc2, td->funnelsink22)));

}
static void
setup_test_objects (struct TestData *td, GstPadChainFunction chain_func)
{
  td->mycaps = gst_caps_new_empty_simple ("test/test");

  td->funnel = gst_element_factory_make ("funnel", NULL);

  td->funnelsrc = gst_element_get_static_pad (td->funnel, "src");
  fail_unless (td->funnelsrc != NULL);

  td->funnelsink11 = gst_element_get_request_pad (td->funnel, "sink_11");
  fail_unless (td->funnelsink11 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink11), "sink_11"));

  td->funnelsink22 = gst_element_get_request_pad (td->funnel, "sink_22");
  fail_unless (td->funnelsink22 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink22), "sink_22"));

  fail_unless (gst_element_set_state (td->funnel, GST_STATE_PLAYING) ==
      GST_STATE_CHANGE_SUCCESS);

  td->mysink = gst_pad_new ("sink", GST_PAD_SINK);
  gst_pad_set_chain_function (td->mysink, chain_func);
  gst_pad_set_active (td->mysink, TRUE);

  td->mysrc1 = gst_pad_new ("src1", GST_PAD_SRC);
  gst_pad_set_active (td->mysrc1, TRUE);
  gst_check_setup_events_with_stream_id (td->mysrc1, td->funnel, td->mycaps,
      GST_FORMAT_BYTES, "test1");

  td->mysrc2 = gst_pad_new ("src2", GST_PAD_SRC);
  gst_pad_set_active (td->mysrc2, TRUE);
  gst_check_setup_events_with_stream_id (td->mysrc2, td->funnel, td->mycaps,
      GST_FORMAT_BYTES, "test2");

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->funnelsrc,
              td->mysink)));

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->mysrc1,
              td->funnelsink11)));

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->mysrc2,
              td->funnelsink22)));

}
static void
pad_added_cb (GstElement * decodebin, GstPad * pad, PlayState * state)
{
  GstPadLinkReturn ret;
  GstElement *fakesink;
  GstPad *fakesink_pad;
  StreamInfo *si;

  fakesink = gst_element_factory_make ("fakesink", NULL);
#if 0
  if (state->n_sinks == 1)
    g_object_set (fakesink, "silent", FALSE, NULL);
#endif

  si = g_new0 (StreamInfo, 1);
  si->pad = g_object_ref (pad);
  si->state = state;
  si->fwd_times = g_array_new (FALSE, TRUE, sizeof (StreamTSRange));
  si->bkwd_times = g_array_new (FALSE, TRUE, sizeof (StreamTSRange));

  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
      (GstPadProbeCallback) handle_output, si, (GDestroyNotify)
      _destroy_stream_info);

  state->n_sinks++;
  gst_bin_add (GST_BIN (state->pipe), fakesink);

  gst_element_sync_state_with_parent (fakesink);

  fakesink_pad = gst_element_get_static_pad (fakesink, "sink");

  ret = gst_pad_link (pad, fakesink_pad);
  if (!GST_PAD_LINK_SUCCESSFUL (ret)) {
    g_printerr ("Failed to link %s:%s to %s:%s (ret = %d)\n",
        GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (fakesink_pad), ret);
  } else {
    GstCaps *caps = gst_pad_get_current_caps (pad);
    gchar *s = gst_caps_to_string (caps);

    g_print ("Linked %s:%s to %s:%s caps %s\n", GST_DEBUG_PAD_NAME (pad),
        GST_DEBUG_PAD_NAME (fakesink_pad), s);
    gst_caps_unref (caps);
    g_free (s);
  }

  gst_object_unref (fakesink_pad);
}
Exemple #8
0
static void
test_pipeline (const char *pipeline)
{
  GstElement *bin, *sink;
  GstPad *pad, *sinkpad;
  GstBus *bus;
  GError *error = NULL;
  GMainLoop *loop;
  GstPadLinkReturn linkret;

  bin = gst_parse_launch (pipeline, &error);
  fail_unless (bin != NULL, "Error parsing pipeline: %s",
      error ? error->message : "(invalid error)");
  pad = gst_bin_find_unlinked_pad (GST_BIN (bin), GST_PAD_SRC);
  fail_unless (pad != NULL, "Could not locate free src pad");

  /* connect the fake sink */
  sink = gst_element_factory_make ("fakesink", "fake_sink");
  fail_unless (sink != NULL, "Could create fakesink");
  fail_unless (gst_bin_add (GST_BIN (bin), sink), "Could not insert fakesink");
  sinkpad = gst_element_get_static_pad (sink, "sink");
  fail_unless (sinkpad != NULL, "Could not get fakesink src pad");

  linkret = gst_pad_link (pad, sinkpad);
  fail_unless (GST_PAD_LINK_SUCCESSFUL (linkret),
      "Could not link to fake sink");
  gst_object_unref (sinkpad);

  /* run until we receive EOS */
  loop = g_main_loop_new (NULL, FALSE);
  bus = gst_element_get_bus (bin);
  gst_bus_add_watch (bus, (GstBusFunc) eos_watch, loop);
  gst_object_unref (bus);

  start_pipeline (bin, pad);
  g_main_loop_run (loop);
  stop_pipeline (bin, pad);

  /* clean up */
  g_main_loop_unref (loop);
  gst_object_unref (pad);
  gst_object_unref (bin);
}
static void
pad_added_cb (GstElement * timeline, GstPad * pad, GstElement * scale)
{
    GstPad *sinkpad;
    GstPadLinkReturn ret;

    sinkpad = gst_element_get_static_pad (scale, "sink");
    if (sinkpad) {
        GST_DEBUG ("got sink pad, trying to link");

        ret = gst_pad_link (pad, sinkpad);
        gst_object_unref (sinkpad);
        if (GST_PAD_LINK_SUCCESSFUL (ret)) {
            GST_DEBUG ("linked ok, returning");
            return;
        }
    }

    GST_DEBUG ("pad failed to link properly");
}
static gboolean
gst_median_link (GstPad * pad, const GstCaps * caps)
{
  GstMedian *filter = GST_MEDIAN (gst_pad_get_parent (pad));
  GstPad *otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
  GstStructure *structure = gst_caps_get_structure (caps, 0);
  gint w, h;
  GstPadLinkReturn ret;

  gst_structure_get_int (structure, "width", &w);
  gst_structure_get_int (structure, "height", &h);

  ret = gst_pad_try_set_caps (otherpad, caps);
  if (GST_PAD_LINK_SUCCESSFUL (ret)) {
    filter->width = w;
    filter->height = h;
  }

  gst_object_unref (filter);

  return ret;
}
Exemple #11
0
static void
pad_added_cb (GstElement * element, GstPad * pad, gint * n_added)
{
  App *app = &s_app;
  GstPad *sinkpad = NULL;
  GstPad *target = NULL;

  if (app->fakesink[*n_added] != NULL) {
    sinkpad = gst_element_get_static_pad (app->fakesink[*n_added], "sink");
    fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (pad, sinkpad)));
    gst_object_unref (sinkpad);

    target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad));
    fail_unless (target != NULL);

    gst_pad_add_probe (target, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
        _appsrc_event_probe, GST_PAD_PARENT (target), NULL);
    gst_object_unref (target);
  }

  *n_added = *n_added + 1;
}
Exemple #12
0
static void
src_pad_added_cb (FsStream *self,
    GstPad   *pad,
    FsCodec  *codec,
    GstElement *pipeline)
{
  GstElement *sink;
  GstPad *sinkpad;

  sink = gst_element_factory_make ("fakesink", NULL);
  g_object_set (sink, "sync", TRUE,
      "signal-handoffs", TRUE,
      NULL);
  g_signal_connect (sink, "handoff", G_CALLBACK (handoff_handler), NULL);
  fail_unless (gst_bin_add (GST_BIN (pipeline), sink));
  gst_element_set_state (sink, GST_STATE_PLAYING);
  sinkpad = gst_element_get_static_pad (sink, "sink");
  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (pad, sinkpad)));
  gst_object_unref (sinkpad);

  GST_DEBUG ("Pad added");
}
int configureAVElement (GstPad* pad, GstElement *element)
{
    int linked = 0;
    GstPad* sinkpad = gst_element_get_static_pad (element, "sink");
    if(!GST_PAD_IS_LINKED(sinkpad))
    {
        linked = GST_PAD_LINK_SUCCESSFUL(gst_pad_link (pad, sinkpad));

        if (!linked)
        {
            g_print ("Gstreamer: Failed to link demux and AV decoders\n");
        }
        else
        {
            g_print("Configured Audio/Video \n");
        }
    }
    else
        g_print("Already linked\n");

    gst_object_unref (sinkpad);

   return linked;
}
Exemple #14
0
//static 
void MediaParserGst::cb_pad_added(GstElement* /* element */, GstPad* new_pad,
                                  gpointer data)
{
    MediaParserGst* parser = static_cast<MediaParserGst*>(data);

    GstCaps* caps = gst_pad_get_caps(new_pad);    
    print_caps(caps);    
    
    GstStructure* str = gst_caps_get_structure (caps, 0);
    if (!str) {
        log_error(_("MediaParserGst: couldn't get structure name."));
        parser->link_to_fakesink(new_pad);
        return;    
    } 
    
    const gchar* caps_name = gst_structure_get_name (str);
    
    bool media_type_audio;

    if (std::equal(caps_name, caps_name+5, "audio")) {
        media_type_audio = true;
    } else if (std::equal(caps_name, caps_name+5, "video")) {
        media_type_audio = false;
    } else {
        log_error(_("MediaParserGst: ignoring stream of type %s."),
                  caps_name);
        parser->link_to_fakesink(new_pad);
        return;
    }    
    
    gboolean parsed = false;
    gboolean framed = false;
    
    gst_structure_get_boolean(str, "parsed", &parsed);
    gst_structure_get_boolean(str, "framed", &framed);
    
    bool already_parsed = parsed || framed;
    
    GstPad* final_pad = 0;
    
    if (already_parsed) {
        final_pad = new_pad;
    } else {
        // We'll try to find a parser, so that we will eventually receive
        // timestamped buffers, on which the MediaParser system relies.
        GstElementFactory* parserfactory = swfdec_gst_get_parser_factory (caps);

        if (!parserfactory) {
            log_error(_("MediaParserGst: Failed to find a parser (media: %s)."),
                      caps_name);
            parser->link_to_fakesink(new_pad);
            return;
        }

        GstElement* parserel = gst_element_factory_create (parserfactory, NULL);
        gst_object_unref (parserfactory);
        if (!parserel) {
            log_error(_("MediaParserGst: Failed to find a parser. We'll continue, "
                        "but either audio or video will not work!"));
            parser->link_to_fakesink(new_pad);
            return;
        }
                     
        gboolean success = gst_bin_add(GST_BIN(parser->_bin), parserel);
        if (!success) {
            gst_object_unref(parserel);
            log_error(_("MediaParserGst: couldn't add parser."));
            parser->link_to_fakesink(new_pad);
            return;
        }
        
        GstPad* sinkpad = gst_element_get_static_pad (parserel, "sink");
        assert(sinkpad);
        
        GstPadLinkReturn ret = gst_pad_link(new_pad, sinkpad);
        
        gst_object_unref(GST_OBJECT(sinkpad));

        if (!GST_PAD_LINK_SUCCESSFUL(ret)) {
            log_error(_("MediaParserGst: couldn't link parser."));
            parser->link_to_fakesink(new_pad);
            return;
        }
        
        final_pad = gst_element_get_static_pad (parserel, "src");
    } 

    if (media_type_audio) {
      
        parser->_audiosink = swfdec_gst_connect_sinkpad_by_pad (final_pad, caps);
        if (!parser->_audiosink) {
            log_error(_("MediaParserGst: couldn't link \"fake\" sink."));
            return;        
        }

        gst_pad_set_chain_function(parser->_audiosink,
                MediaParserGst::cb_chain_func_audio);
        
        g_object_set_data(G_OBJECT (parser->_audiosink), "mediaparser-obj",
                parser);
        
        LOG_ONCE(
            log_unimpl("MediaParserGst won't set codec, sampleRate, "
                "sampleSize, stereo and duration in AudioInfo"); 
        );
        AudioInfo* audioinfo = new AudioInfo(0, 0, 0, false, 0,
                CODEC_TYPE_CUSTOM);
        audioinfo->extra.reset(new ExtraInfoGst(caps));

        parser->_audioInfo.reset(audioinfo);
        log_debug(_("MediaParserGst: Linked audio source (type: %s)"), caps_name); 

    } else {
Exemple #15
0
static gboolean
gst_goo_encjpeg_setcaps (GstPad* pad, GstCaps* caps)
{
	GstGooEncJpeg* self = GST_GOO_ENCJPEG (gst_pad_get_parent (pad));
	GstGooEncJpegPrivate* priv = GST_GOO_ENCJPEG_GET_PRIVATE (self);

	GstStructure* structure;
	const GValue* framerate;
	guint32 fourcc;
	GstPad* otherpad;
	GstCaps* othercaps;
	gboolean ret;

	otherpad = (pad == self->srcpad) ? self->sinkpad : self->srcpad;
	othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));

	structure = gst_caps_get_structure (caps, 0);

	gst_structure_get_int (structure, "width", &priv->width);
	gst_structure_get_int (structure, "height", &priv->height);
	gst_structure_get_fourcc (structure, "format", &fourcc);

	switch (fourcc)
	{
	case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
		priv->colorformat = OMX_COLOR_FormatCbYCrY;
		break;
	case GST_MAKE_FOURCC ('I', '4', '2', '0'):
		priv->colorformat = OMX_COLOR_FormatYUV420PackedPlanar;
		break;
	default:
		GST_ERROR ("format not supported");
		return FALSE;
	}

	g_object_set (self->component, "width", priv->width, NULL);
	g_object_set (self->component, "height", priv->height, NULL);

	priv->omxbufsiz = (priv->colorformat == OMX_COLOR_FormatCbYCrY) ?
		priv->width * priv->height * 2 :
		priv->width * priv->height * 1.5;

	framerate = gst_structure_get_value (structure, "framerate");

	if (G_LIKELY (framerate))
	{
		gst_caps_set_simple
			(othercaps,
			 "width", G_TYPE_INT, priv->width,
			 "height", G_TYPE_INT, priv->height,
			 "framerate", GST_TYPE_FRACTION,
			 gst_value_get_fraction_numerator (framerate),
			 gst_value_get_fraction_denominator (framerate),
			 NULL);
	}
	else
	{
		gst_caps_set_simple
			(othercaps,
			 "width", G_TYPE_INT, priv->width,
			 "height", G_TYPE_INT, priv->height,
			 NULL);
	}

	ret = gst_pad_set_caps (self->srcpad, othercaps);
	gst_caps_unref (othercaps);

	if (GST_PAD_LINK_SUCCESSFUL (ret) &&
	    goo_component_get_state (self->component) == OMX_StateLoaded)
	{
		omx_start (self);
	}

	gst_object_unref (self);

	return ret;
}
Exemple #16
0
static TestSession*
add_audio_session (GstElement *pipeline, FsConference *conf, guint id,
    FsParticipant *part, gchar *send_socket, gchar *recv_socket)
{
  TestSession *ses = g_slice_new0 (TestSession);
  GError *error = NULL;
  GstPad *pad = NULL, *pad2 = NULL;
  GstElement *src = NULL;
  GList *cands = NULL;
  GParameter param = {0};
  gboolean res;
  FsCandidate *cand;
  GList *codecs = NULL;

  ses->send_socket = send_socket;
  ses->recv_socket = recv_socket;

  ses->session = fs_conference_new_session (conf, FS_MEDIA_TYPE_AUDIO, &error);
  print_error (error);
  g_assert (ses->session);

  g_object_get (ses->session, "sink-pad", &pad, NULL);

  if (g_getenv ("AUDIOSRC"))
    src = gst_parse_bin_from_description (g_getenv ("AUDIOSRC"), TRUE,
        &error);
  else
    src = gst_parse_bin_from_description (DEFAULT_AUDIOSRC, TRUE,
        &error);
  print_error (error);
  g_assert (src);

  g_assert (gst_bin_add (GST_BIN (pipeline), src));

  pad2 = gst_element_get_static_pad (src, "src");
  g_assert (pad2);

  g_assert (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (pad2, pad)));

  gst_object_unref (pad2);
  gst_object_unref (pad);

  ses->stream = fs_session_new_stream (ses->session, part, FS_DIRECTION_BOTH,
      &error);
  print_error (error);
  g_assert (ses->stream);

  cand = fs_candidate_new ("", FS_COMPONENT_RTP,
      FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, send_socket, 0);
  cands = g_list_prepend (NULL, cand);

  param.name = "preferred-local-candidates";
  g_value_init (&param.value, FS_TYPE_CANDIDATE_LIST);
  g_value_take_boxed (&param.value, cands);

  res = fs_stream_set_transmitter (ses->stream, "shm", &param, 1, &error);
  print_error (error);
  g_value_unset (&param.value);

  g_signal_connect (ses->stream, "src-pad-added",
      G_CALLBACK (src_pad_added_cb), pipeline);

  codecs = g_list_prepend (NULL,
      fs_codec_new (FS_CODEC_ID_ANY, "PCMA", FS_MEDIA_TYPE_AUDIO, 0));
  codecs = g_list_prepend (codecs,
      fs_codec_new (FS_CODEC_ID_ANY, "PCMU", FS_MEDIA_TYPE_AUDIO, 0));

  res = fs_session_set_codec_preferences (ses->session, codecs, &error);
  print_error (error);
  fs_codec_list_destroy (codecs);


  g_object_get (ses->session, "codecs-without-config", &codecs, NULL);
  res = fs_stream_set_remote_codecs (ses->stream, codecs, &error);
  print_error (error);
  g_assert (res);


  return ses;
}
static void
gst_insert_bin_do_change (GstInsertBin * self, GstPad * pad)
{
  struct ChangeData *data;

  GST_OBJECT_LOCK (self);

  if (!is_right_direction_for_block (pad)) {
    GST_WARNING_OBJECT (self, "Block pad does not have the expected direction");
    goto next;
  }

  while ((data = g_queue_pop_head (&self->priv->change_queue)) != NULL) {
    GstPad *peer = NULL;
    GstPad *other_peer = NULL;

    GST_OBJECT_UNLOCK (self);


    if (data->action == GST_INSERT_BIN_ACTION_ADD &&
        !validate_element (self, data->element))
      goto error;

    peer = gst_pad_get_peer (pad);

    if (peer == NULL) {
      GST_WARNING_OBJECT (self, "Blocked pad has no peer");
      goto error;
    }

    if (data->action == GST_INSERT_BIN_ACTION_ADD) {
      GstPad *srcpad = NULL, *sinkpad = NULL;
      GstPad *peersrcpad, *peersinkpad;

      /* First let's make sure we have the right pad */
      if (data->sibling) {
        GstElement *parent = NULL;
        GstPad *siblingpad;

        if ((gst_pad_get_direction (pad) == GST_PAD_SRC &&
                data->direction == DIRECTION_BEFORE) ||
            (gst_pad_get_direction (pad) == GST_PAD_SINK &&
                data->direction == DIRECTION_AFTER))
          siblingpad = peer;
        else
          siblingpad = pad;

        parent = gst_pad_get_parent_element (siblingpad);
        if (parent != NULL)
          gst_object_unref (parent);

        if (parent != data->sibling)
          goto retry;
      } else {
        GstObject *parent;
        GstPad *ghost;
        GstPad *proxypad;

        if (data->direction == DIRECTION_BEFORE) {
          ghost = self->priv->srcpad;
          if (gst_pad_get_direction (pad) == GST_PAD_SINK)
            proxypad = pad;
          else
            proxypad = peer;
        } else {
          ghost = self->priv->sinkpad;
          if (gst_pad_get_direction (pad) == GST_PAD_SINK)
            proxypad = peer;
          else
            proxypad = pad;
        }

        if (!GST_IS_PROXY_PAD (proxypad))
          goto retry;
        parent = gst_pad_get_parent (proxypad);
        if (!parent)
          goto retry;
        gst_object_unref (parent);
        if (GST_PAD_CAST (parent) != ghost)
          goto retry;
      }

      if (gst_pad_get_direction (pad) == GST_PAD_SRC) {
        peersrcpad = pad;
        peersinkpad = peer;
      } else {
        peersrcpad = peer;
        peersinkpad = pad;
      }

      if (GST_IS_PROXY_PAD (peersrcpad)) {
        GstObject *parent = gst_pad_get_parent (peersrcpad);

        if (GST_PAD_CAST (parent) == self->priv->sinkpad)
          peersrcpad = NULL;

        if (parent)
          gst_object_unref (parent);
      }

      if (GST_IS_PROXY_PAD (peersinkpad)) {
        GstObject *parent = gst_pad_get_parent (peersinkpad);

        if (GST_PAD_CAST (parent) == self->priv->srcpad)
          peersinkpad = NULL;

        if (parent)
          gst_object_unref (parent);
      }

      if (peersinkpad && peersrcpad) {
        gst_pad_unlink (peersrcpad, peersinkpad);
      } else {
        if (!peersinkpad)
          gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad), NULL);
        if (!peersrcpad)
          gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad), NULL);
      }

      srcpad = get_single_pad (data->element, GST_PAD_SRC);
      sinkpad = get_single_pad (data->element, GST_PAD_SINK);

      if (srcpad == NULL || sinkpad == NULL) {
        GST_WARNING_OBJECT (self, "Can not get element src or sink pad");
        goto error;
      }

      if (!gst_bin_add (GST_BIN (self), data->element)) {
        GST_WARNING_OBJECT (self, "Can not add element to bin");
        goto error;
      }

      if (peersrcpad) {
        if (GST_PAD_LINK_FAILED (gst_pad_link (peersrcpad, sinkpad))) {
          GST_WARNING_OBJECT (self, "Can not link sibling's %s:%s pad"
              " to element's %s:%s pad", GST_DEBUG_PAD_NAME (peersrcpad),
              GST_DEBUG_PAD_NAME (sinkpad));
          goto error;
        }
      } else {
        if (!gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad),
                sinkpad)) {
          GST_WARNING_OBJECT (self, "Can not set %s:%s as target for %s:%s",
              GST_DEBUG_PAD_NAME (sinkpad),
              GST_DEBUG_PAD_NAME (self->priv->sinkpad));
          goto error;
        }
      }

      if (peersinkpad) {
        if (GST_PAD_LINK_FAILED (gst_pad_link (srcpad, peersinkpad))) {
          GST_WARNING_OBJECT (self, "Can not link element's %s:%s pad"
              " to sibling's %s:%s pad", GST_DEBUG_PAD_NAME (srcpad),
              GST_DEBUG_PAD_NAME (peersinkpad));
          goto error;
        }
      } else {
        if (!gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad),
                srcpad)) {
          GST_WARNING_OBJECT (self, "Can not set %s:%s as target for %s:%s",
              GST_DEBUG_PAD_NAME (srcpad),
              GST_DEBUG_PAD_NAME (self->priv->srcpad));
          goto error;
        }
      }

      gst_object_unref (srcpad);
      gst_object_unref (sinkpad);

      if (!gst_element_sync_state_with_parent (data->element)) {
        GST_WARNING_OBJECT (self, "Can not sync element's state with parent");
        goto error;
      }
    } else {
      GstElement *parent = NULL;
      GstPad *other_pad;
      GstCaps *caps = NULL, *peercaps = NULL;
      gboolean can_intersect;
      gboolean success;

      parent = gst_pad_get_parent_element (peer);
      if (parent != NULL)
        gst_object_unref (parent);

      if (parent != data->element)
        goto retry;

      if (gst_pad_get_direction (peer) == GST_PAD_SRC)
        other_pad = get_single_pad (data->element, GST_PAD_SINK);
      else
        other_pad = get_single_pad (data->element, GST_PAD_SRC);

      if (!other_pad) {
        GST_WARNING_OBJECT (self, "Can not get element's other pad");
        goto error;
      }

      other_peer = gst_pad_get_peer (other_pad);
      gst_object_unref (other_pad);

      if (!other_peer) {
        GST_WARNING_OBJECT (self, "Can not get element's other peer");
        goto error;
      }

      /* Get the negotiated caps for the source pad peer,
       * because renegotiation while the pipeline is playing doesn't work
       * that fast.
       */
      if (gst_pad_get_direction (pad) == GST_PAD_SRC)
        caps = gst_pad_get_current_caps (pad);
      else
        peercaps = gst_pad_get_current_caps (other_peer);
      if (!caps)
        caps = gst_pad_query_caps (pad, NULL);
      if (!peercaps)
        peercaps = gst_pad_query_caps (other_peer, NULL);
      can_intersect = gst_caps_can_intersect (caps, peercaps);
      gst_caps_unref (caps);
      gst_caps_unref (peercaps);

      if (!can_intersect) {
        GST_WARNING_OBJECT (self, "Pads are incompatible without the element");
        goto error;
      }

      if (gst_pad_get_direction (other_peer) == GST_PAD_SRC &&
          gst_pad_is_active (other_peer)) {
        gulong probe_id;

        probe_id = gst_pad_add_probe (other_peer,
            GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
            wait_and_drop_eos_cb, NULL, NULL);
        gst_pad_send_event (peer, gst_event_new_eos ());
        gst_pad_remove_probe (other_peer, probe_id);
      }

      gst_element_set_locked_state (data->element, TRUE);
      gst_element_set_state (data->element, GST_STATE_NULL);
      if (!gst_bin_remove (GST_BIN (self), data->element)) {
        GST_WARNING_OBJECT (self, "Element removal rejected");
        goto error;
      }
      gst_element_set_locked_state (data->element, FALSE);

      if (gst_pad_get_direction (pad) == GST_PAD_SRC)
        success = GST_PAD_LINK_SUCCESSFUL (gst_pad_link_full (pad, other_peer,
                GST_PAD_LINK_CHECK_HIERARCHY |
                GST_PAD_LINK_CHECK_TEMPLATE_CAPS));
      else
        success = GST_PAD_LINK_SUCCESSFUL (gst_pad_link_full (other_peer, pad,
                GST_PAD_LINK_CHECK_HIERARCHY |
                GST_PAD_LINK_CHECK_TEMPLATE_CAPS));
      gst_object_unref (other_peer);
      other_peer = NULL;

      if (!success) {
        GST_ERROR_OBJECT (self, "Could not re-link after the element's"
            " removal");
        goto error;
      }
    }


    gst_insert_bin_change_data_complete (self, data, TRUE);
    gst_object_unref (peer);

    GST_OBJECT_LOCK (self);
    continue;
  done:
    if (other_peer != NULL)
      gst_object_unref (other_peer);

    if (peer != NULL)
      gst_object_unref (peer);
    break;
  retry:
    GST_OBJECT_LOCK (self);
    g_queue_push_head (&self->priv->change_queue, data);
    goto done;
  error:
    /* Handle error */
    gst_insert_bin_change_data_complete (self, data, FALSE);
    GST_OBJECT_LOCK (self);
    goto done;
  }

next:
  gst_insert_bin_block_pad_unlock (self);
}
Exemple #18
0
static void
test_pipeline (const char *pipeline)
{
  GstElement *bin, *sink;
  GstPad *pad, *sinkpad;
  GstBus *bus;
  GError *error = NULL;
  GMainLoop *loop;
  GstPadLinkReturn linkret;
  guint bus_watch = 0;

  bin = gst_parse_launch (pipeline, &error);
  fail_unless (bin != NULL, "Error parsing pipeline: %s",
      error ? error->message : "(invalid error)");
  pad = gst_bin_find_unlinked_pad (GST_BIN (bin), GST_PAD_SRC);
  fail_unless (pad != NULL, "Could not locate free src pad");

  /* connect the fake sink */
  sink = gst_element_factory_make ("fakesink", "fake_sink");
  fail_unless (sink != NULL, "Could create fakesink");
  fail_unless (gst_bin_add (GST_BIN (bin), sink), "Could not insert fakesink");
  sinkpad = gst_element_get_static_pad (sink, "sink");
  fail_unless (sinkpad != NULL, "Could not get fakesink src pad");

  linkret = gst_pad_link (pad, sinkpad);
  fail_unless (GST_PAD_LINK_SUCCESSFUL (linkret),
      "Could not link to fake sink");
  gst_object_unref (sinkpad);

  /* run until we receive EOS */
  loop = g_main_loop_new (NULL, FALSE);
  bus = gst_element_get_bus (bin);
  bus_watch = gst_bus_add_watch (bus, (GstBusFunc) eos_watch, loop);
  gst_object_unref (bus);

  start_pipeline (bin, pad);
  g_main_loop_run (loop);

  /* we're EOS now; make sure oggmux out caps have stream headers on them */
  {
    GstStructure *s;
    GstCaps *muxcaps;

    muxcaps = gst_pad_get_negotiated_caps (sinkpad);
    fail_unless (muxcaps != NULL);
    s = gst_caps_get_structure (muxcaps, 0);
    fail_unless (gst_structure_has_name (s, "application/ogg"));
    fail_unless (gst_structure_has_field (s, "streamheader"));
    fail_unless (gst_structure_has_field_typed (s, "streamheader",
            GST_TYPE_ARRAY));
    gst_caps_unref (muxcaps);
  }

  stop_pipeline (bin, pad);

  /* clean up */
  g_main_loop_unref (loop);
  g_source_remove (bus_watch);
  gst_object_unref (pad);
  gst_object_unref (bin);
}