void NWaveformBuilderGstreamer::update()
{
	GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_playbin));
	GstMessage *msg = gst_bus_pop_filtered(bus, GstMessageType(GST_MESSAGE_EOS | GST_MESSAGE_ERROR));
	if (msg) {
		switch (GST_MESSAGE_TYPE(msg)) {
			case GST_MESSAGE_EOS:
				peaks()->complete();
#if defined(QT_DEBUG) && !defined(QT_NO_DEBUG)
				qDebug() <<  "WaveformBuilder ::" << "completed" << peaks()->size();
#endif
				stop();
				break;
			case GST_MESSAGE_ERROR:
#if defined(QT_DEBUG) && !defined(QT_NO_DEBUG)
				gchar *debug;
				GError *err = NULL;

				gst_message_parse_error(msg, &err, &debug);
				g_free(debug);

				qWarning() << "WaveformBuilder :: error ::" << QString::fromUtf8(err->message);
				if (err)
					g_error_free(err);
#endif
				break;
			default:
				break;
		}
		gst_message_unref(msg);
	}
	gst_object_unref(bus);
}
Example #2
0
static void
check_get_dtmf_event_message (GstBus * bus, gint number, gint volume)
{
  GstMessage *message;
  gboolean have_message = FALSE;

  while (!have_message &&
      (message = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT)) != NULL) {
    if (gst_message_has_name (message, "dtmf-event")) {
      const GstStructure *s = gst_message_get_structure (message);
      gint stype, snumber, smethod, svolume;

      fail_unless (gst_structure_get (s,
              "type", G_TYPE_INT, &stype,
              "number", G_TYPE_INT, &snumber,
              "method", G_TYPE_INT, &smethod,
              "volume", G_TYPE_INT, &svolume, NULL));

      fail_unless (stype == 1);
      fail_unless (smethod == 1);
      fail_unless (snumber == number);
      fail_unless (svolume == volume);
      have_message = TRUE;
    }
    gst_message_unref (message);
  }

  fail_unless (have_message);
}
Example #3
0
CAMLprim value ocaml_gstreamer_bus_pop_filtered(value _bus, value _filter)
{
  CAMLparam2(_bus, _filter);
  CAMLlocal1(ans);
  GstBus *bus = Bus_val(_bus);
  GstMessageType filter = 0;
  GstMessage *msg;
  int i;

  for(i = 0; i < Wosize_val(_filter); i++)
    filter |= message_type_of_int(Int_val(Field(_filter, i)));

  caml_release_runtime_system();
  msg = gst_bus_pop_filtered(bus, filter);
  caml_acquire_runtime_system();

  if(!msg)
    ans = Val_int(0);
  else
    {
      ans = caml_alloc_tuple(1);
      Store_field(ans, 0, value_of_message(msg));
    }

  CAMLreturn(ans);
}
Example #4
0
bool tcStreamWrapper::end_of_stream()
{
    if(mpPLine == NULL)
        return false;
#ifndef WIN32
	return mpPLine->endofstream;
#else
	// Windows Qt doesn't hook into the gst main loop
	// so we need to poll it and see if there is an
	// end of line message posted
	GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(mpPLine->pipeline));
	return gst_bus_pop_filtered(bus, GST_MESSAGE_EOS) != NULL;
#endif
}
Example #5
0
static void
check_no_dtmf_event_message (GstBus * bus)
{
  GstMessage *message;
  gboolean have_message = FALSE;

  while (!have_message &&
      (message = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT)) != NULL) {
    if (gst_message_has_name (message, "dtmf-event") ||
        gst_message_has_name (message, "dtmf-event-processed") ||
        gst_message_has_name (message, "dtmf-event-dropped")) {
      have_message = TRUE;
    }
    gst_message_unref (message);
  }

  fail_unless (!have_message);
}
Example #6
0
/*
 * cheese_camera_device_get_caps:
 * @device: a #CheeseCameraDevice
 *
 * Probe the #GstCaps that the @device supports.
 */
static void
cheese_camera_device_get_caps (CheeseCameraDevice *device)
{
  CheeseCameraDevicePrivate *priv = device->priv;

  gchar               *pipeline_desc;
  GstElement          *pipeline;
  GstStateChangeReturn ret;
  GstMessage          *msg;
  GstBus              *bus;
  GError              *err = NULL;

  pipeline_desc = g_strdup_printf ("%s name=source device=%s ! fakesink",
                                   priv->src, priv->device_node);
  pipeline = gst_parse_launch (pipeline_desc, &err);
  if ((pipeline != NULL) && (err == NULL))
  {
    /* Start the pipeline and wait for max. 10 seconds for it to start up */
    gst_element_set_state (pipeline, GST_STATE_READY);
    ret = gst_element_get_state (pipeline, NULL, NULL, 10 * GST_SECOND);

    /* Check if any error messages were posted on the bus */
    bus = gst_element_get_bus (pipeline);
    msg = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR);
    gst_object_unref (bus);

    if ((msg == NULL) && (ret == GST_STATE_CHANGE_SUCCESS))
    {
      GstElement *src;
      GstPad     *pad;
      GstCaps    *caps;

      src = gst_bin_get_by_name (GST_BIN (pipeline), "source");

      GST_LOG ("Device: %s (%s)\n", priv->name, priv->device_node);
      pad        = gst_element_get_static_pad (src, "src");
      caps       = gst_pad_get_allowed_caps (pad);

      gst_caps_unref (priv->caps);
      priv->caps = cheese_camera_device_filter_caps (device, caps, supported_formats);

      if (!gst_caps_is_empty (priv->caps))
        cheese_camera_device_update_format_table (device);
      else
      {
        g_set_error_literal (&priv->construct_error,
                             CHEESE_CAMERA_DEVICE_ERROR,
                             CHEESE_CAMERA_DEVICE_ERROR_UNSUPPORTED_CAPS,
                             _("Device capabilities not supported"));
      }

      gst_object_unref (pad);
      gst_caps_unref (caps);
      gst_object_unref (src);
    }
    else
    {
      if (msg)
      {
        gchar *dbg_info = NULL;
        gst_message_parse_error (msg, &err, &dbg_info);
        GST_WARNING ("Failed to start the capability probing pipeline");
        GST_WARNING ("Error from element %s: %s, %s",
                     GST_OBJECT_NAME (msg->src),
                     err->message,
                     (dbg_info) ? dbg_info : "no extra debug detail");
        g_error_free (err);
        err = NULL;

        /* construct_error is meant to be displayed in the UI
         * (although it currently isn't displayed in cheese),
         * err->message from gstreamer is too technical for this
         * purpose, the idea is warn the user about an error and point
         * him to the logs for more info */
        g_set_error (&priv->construct_error,
                     CHEESE_CAMERA_DEVICE_ERROR,
                     CHEESE_CAMERA_DEVICE_ERROR_FAILED_INITIALIZATION,
                     _("Failed to initialize device %s for capability probing"),
                     priv->device_node);
      }
    }
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);
  }

  if (err)
    g_error_free (err);

  g_free (pipeline_desc);
}
Example #7
0
static GstElement *
gst_auto_video_src_find_best (GstAutoVideoSrc * src)
{
  GList *list, *item;
  GstElement *choice = NULL;
  GstMessage *message = NULL;
  GSList *errors = NULL;
  GstBus *bus = gst_bus_new ();
  GstPad *el_pad = NULL;
  GstCaps *el_caps = NULL, *intersect = NULL;
  gboolean no_match = TRUE;

  list = gst_registry_feature_filter (gst_registry_get_default (),
      (GstPluginFeatureFilter) gst_auto_video_src_factory_filter, FALSE, src);
  list = g_list_sort (list, (GCompareFunc) gst_auto_video_src_compare_ranks);

  GST_LOG_OBJECT (src, "Trying to find usable video devices ...");

  for (item = list; item != NULL; item = item->next) {
    GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
    GstElement *el;

    if ((el = gst_auto_video_src_create_element_with_pretty_name (src, f))) {
      GstStateChangeReturn ret;

      GST_DEBUG_OBJECT (src, "Testing %s", GST_PLUGIN_FEATURE (f)->name);

      /* If AutoVideoSrc has been provided with filter caps,
       * accept only sources that match with the filter caps */
      if (src->filter_caps) {
        el_pad = gst_element_get_static_pad (GST_ELEMENT (el), "src");
        el_caps = gst_pad_get_caps (el_pad);
        gst_object_unref (el_pad);
        GST_DEBUG_OBJECT (src,
            "Checking caps: %" GST_PTR_FORMAT " vs. %" GST_PTR_FORMAT,
            src->filter_caps, el_caps);
        intersect = gst_caps_intersect (src->filter_caps, el_caps);
        no_match = gst_caps_is_empty (intersect);
        gst_caps_unref (el_caps);
        gst_caps_unref (intersect);

        if (no_match) {
          GST_DEBUG_OBJECT (src, "Incompatible caps");
          gst_object_unref (el);
          continue;
        } else {
          GST_DEBUG_OBJECT (src, "Found compatible caps");
        }
      }

      gst_element_set_bus (el, bus);
      ret = gst_element_set_state (el, GST_STATE_READY);
      if (ret == GST_STATE_CHANGE_SUCCESS) {
        GST_DEBUG_OBJECT (src, "This worked!");
        choice = el;
        break;
      }

      /* collect all error messages */
      while ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR))) {
        GST_DEBUG_OBJECT (src, "error message %" GST_PTR_FORMAT, message);
        errors = g_slist_append (errors, message);
      }

      gst_element_set_state (el, GST_STATE_NULL);
      gst_object_unref (el);
    }
  }

  GST_DEBUG_OBJECT (src, "done trying");
  if (!choice) {
    if (errors) {
      /* FIXME: we forward the first error for now; but later on it might make
       * sense to actually analyse them */
      gst_message_ref (GST_MESSAGE (errors->data));
      GST_DEBUG_OBJECT (src, "reposting message %p", errors->data);
      gst_element_post_message (GST_ELEMENT (src), GST_MESSAGE (errors->data));
    } else {
      /* send warning message to application and use a fakesrc */
      GST_ELEMENT_WARNING (src, RESOURCE, NOT_FOUND, (NULL),
          ("Failed to find a usable video source"));
      choice = gst_element_factory_make ("fakesrc", "fake-video-src");
      if (g_object_class_find_property (G_OBJECT_GET_CLASS (choice), "sync"))
        g_object_set (choice, "sync", TRUE, NULL);
      gst_element_set_state (choice, GST_STATE_READY);
    }
  }
  gst_object_unref (bus);
  gst_plugin_feature_list_free (list);
  g_slist_foreach (errors, (GFunc) gst_mini_object_unref, NULL);
  g_slist_free (errors);

  return choice;
}
void NPlaybackEngineGStreamer::checkStatus()
{
	GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_playbin));
	GstMessage *msg;
	while ((msg = gst_bus_pop_filtered(bus, GstMessageType(GST_MESSAGE_EOS | GST_MESSAGE_ERROR))) != NULL) {
		switch (GST_MESSAGE_TYPE(msg)) {
			case GST_MESSAGE_EOS: {
				stop();
				emit finished();
				emit stateChanged(m_oldState = N::PlaybackStopped);
				break;
			}
			case GST_MESSAGE_ERROR: {
				gchar *debug;
				GError *err = NULL;
				gst_message_parse_error(msg, &err, &debug);
				g_free(debug);

				emit message(QMessageBox::Critical, QFileInfo(m_currentMedia).absoluteFilePath(), err ? QString::fromUtf8(err->message) : "unknown error");
				fail();

				if (err)
					g_error_free(err);
				break;
			}
			default:
				break;
		}
		gst_message_unref(msg);
	}
	gst_object_unref(bus);

	GstState gstState;
	if (gst_element_get_state(m_playbin, &gstState, NULL, 0) != GST_STATE_CHANGE_SUCCESS)
		return;

	N::PlaybackState state = fromGstState(gstState);
	if (m_oldState != state)
		emit stateChanged(m_oldState = state);

	if (state == N::PlaybackPlaying || state == N::PlaybackPaused) {
		// duration may change for some reason
		// TODO use DURATION_CHANGED in gstreamer1.0
		gboolean res = gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &m_durationNsec);
		if (!res)
			m_durationNsec = 0;
	}

	if (m_posponedPosition >= 0 && m_durationNsec > 0) {
		setPosition(m_posponedPosition);
		m_posponedPosition = -1;
		emit positionChanged(m_posponedPosition);
	} else {
		qreal pos;
		gint64 gstPos = 0;

		if (!hasMedia() || m_durationNsec <= 0) {
			pos = -1;
		} else {
			gboolean res = gst_element_query_position(m_playbin, GST_FORMAT_TIME, &gstPos);
			if (!res)
				gstPos = 0;
			pos = (qreal)gstPos / m_durationNsec;
		}

		if (m_oldPosition != pos) {
			if (m_oldPosition > pos)
				m_crossfading = false;
			m_oldPosition = pos;
			emit positionChanged(m_crossfading ? 0 : m_oldPosition);
		}

		emit tick(m_crossfading ? 0 : gstPos / NSEC_IN_MSEC);
	}

	qreal vol = volume();
	if (qAbs(m_oldVolume - vol) > 0.0001) {
		m_oldVolume = vol;
		emit volumeChanged(vol);
	}

	if (state == N::PlaybackStopped)
		m_timer->stop();
}
Example #9
0
static gboolean
gst_switch_commit_new_kid (GstSwitchSink * sink)
{
  GstPad *targetpad;
  GstState kid_state;
  GstElement *new_kid, *old_kid;
  gboolean is_fakesink = FALSE;
  GstBus *bus;

  /* need locking around member accesses */
  GST_OBJECT_LOCK (sink);
  /* If we're currently changing state, set the child to the next state
   * we're transitioning too, rather than our current state which is 
   * about to change */
  if (GST_STATE_NEXT (sink) != GST_STATE_VOID_PENDING)
    kid_state = GST_STATE_NEXT (sink);
  else
    kid_state = GST_STATE (sink);

  new_kid = sink->new_kid;
  sink->new_kid = NULL;
  GST_OBJECT_UNLOCK (sink);

  /* Fakesink by default if NULL is passed as the new child */
  if (new_kid == NULL) {
    GST_DEBUG_OBJECT (sink, "Replacing kid with fakesink");
    new_kid = gst_element_factory_make ("fakesink", "testsink");
    if (new_kid == NULL) {
      GST_ERROR_OBJECT (sink, "Failed to create fakesink");
      return FALSE;
    }
    /* Add a reference, as it would if the element came from sink->new_kid */
    gst_object_ref (new_kid);
    g_object_set (new_kid, "sync", TRUE, NULL);
    is_fakesink = TRUE;
  } else {
    GST_DEBUG_OBJECT (sink, "Setting new kid");
  }

  /* set temporary bus of our own to catch error messages from the child
   * (could we just set our own bus on it, or would the state change messages
   * from the not-yet-added element confuse the state change algorithm? Let's
   * play it safe for now) */
  bus = gst_bus_new ();
  gst_element_set_bus (new_kid, bus);
  gst_object_unref (bus);

  if (gst_element_set_state (new_kid, kid_state) == GST_STATE_CHANGE_FAILURE) {
    GstMessage *msg;

    /* check if child posted an error message and if so re-post it on our bus
     * so that the application gets to see a decent error and not our generic
     * fallback error message which is completely indecipherable to the user */
    msg = gst_bus_pop_filtered (GST_ELEMENT_BUS (new_kid), GST_MESSAGE_ERROR);
    if (msg) {
      GST_INFO_OBJECT (sink, "Forwarding kid error: %" GST_PTR_FORMAT, msg);
      gst_element_post_message (GST_ELEMENT (sink), msg);
    }
    /* FIXME: need a translated error message that tells the user to check
     * her GConf audio/video settings */
    GST_ELEMENT_ERROR (sink, CORE, STATE_CHANGE, (NULL),
        ("Failed to set state on new child."));
    gst_element_set_bus (new_kid, NULL);
    gst_object_unref (new_kid);
    return FALSE;
  }
  gst_element_set_bus (new_kid, NULL);
  gst_bin_add (GST_BIN (sink), new_kid);

  /* Now, replace the existing child */
  GST_OBJECT_LOCK (sink);
  old_kid = sink->kid;
  sink->kid = new_kid;
  /* Mark whether a custom kid or fakesink has been installed */
  sink->have_kid = !is_fakesink;
  GST_OBJECT_UNLOCK (sink);

  /* kill old element */
  if (old_kid) {
    GST_DEBUG_OBJECT (sink, "Removing old kid %" GST_PTR_FORMAT, old_kid);
    gst_element_set_state (old_kid, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (sink), old_kid);
    gst_object_unref (old_kid);
  }

  /* re-attach ghostpad */
  GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
  targetpad = gst_element_get_static_pad (sink->kid, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
  gst_object_unref (targetpad);
  GST_DEBUG_OBJECT (sink, "done changing child of switchsink");

  /* FIXME: Push new-segment info and pre-roll buffer(s) into the kid */

  /* Unblock the target pad if necessary */
  if (sink->awaiting_block) {
    gst_pad_set_blocked (sink->pad, FALSE);
    sink->awaiting_block = FALSE;
  }

  return TRUE;
}
Example #10
0
/* Decode */
static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    block_t *p_block;
    picture_t *p_pic = NULL;
    decoder_sys_t *p_sys = p_dec->p_sys;
    GstMessage *p_msg;
    GstBuffer *p_buf;

    if( !pp_block )
        return NULL;

    p_block = *pp_block;

    if( !p_block )
        goto check_messages;

    if( unlikely( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY |
                    BLOCK_FLAG_CORRUPTED ) ) )
    {
        if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
            Flush( p_dec );

        if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
        {
            block_Release( p_block );
            goto done;
        }
    }

    if( likely( p_block->i_buffer ) )
    {
        p_buf = gst_buffer_new_wrapped_full( GST_MEMORY_FLAG_READONLY,
                p_block->p_start, p_block->i_size,
                p_block->p_buffer - p_block->p_start, p_block->i_buffer,
                p_block, ( GDestroyNotify )block_Release );
        if( unlikely( p_buf == NULL ) )
        {
            msg_Err( p_dec, "failed to create input gstbuffer" );
            p_dec->b_error = true;
            block_Release( p_block );
            goto done;
        }

        if( p_block->i_dts > VLC_TS_INVALID )
            GST_BUFFER_DTS( p_buf ) = gst_util_uint64_scale( p_block->i_dts,
                    GST_SECOND, GST_MSECOND );

        if( p_block->i_pts <= VLC_TS_INVALID )
            GST_BUFFER_PTS( p_buf ) = GST_BUFFER_DTS( p_buf );
        else
            GST_BUFFER_PTS( p_buf ) = gst_util_uint64_scale( p_block->i_pts,
                    GST_SECOND, GST_MSECOND );

        if( p_block->i_length > VLC_TS_INVALID )
            GST_BUFFER_DURATION( p_buf ) = gst_util_uint64_scale(
                    p_block->i_length, GST_SECOND, GST_MSECOND );

        if( p_dec->fmt_in.video.i_frame_rate  &&
                p_dec->fmt_in.video.i_frame_rate_base )
            GST_BUFFER_DURATION( p_buf ) = gst_util_uint64_scale( GST_SECOND,
                    p_dec->fmt_in.video.i_frame_rate_base,
                    p_dec->fmt_in.video.i_frame_rate );

        /* Give the input buffer to GStreamer Bin.
         *
         *  libvlc                      libvlc
         *    \ (i/p)              (o/p) ^
         *     \                        /
         *   ___v____GSTREAMER BIN_____/____
         *  |                               |
         *  |   appsrc-->decode-->vlcsink   |
         *  |_______________________________|
         *
         * * * * * * * * * * * * * * * * * * * * */
        if( unlikely( gst_app_src_push_buffer(
                        GST_APP_SRC_CAST( p_sys->p_decode_src ), p_buf )
                    != GST_FLOW_OK ) )
        {
            /* block will be released internally,
             * when gst_buffer_unref() is called */
            p_dec->b_error = true;
            msg_Err( p_dec, "failed to push buffer" );
            goto done;
        }
    }
    else
        block_Release( p_block );

check_messages:
    /* Poll for any messages, errors */
    p_msg = gst_bus_pop_filtered( p_sys->p_bus,
            GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR |
            GST_MESSAGE_EOS | GST_MESSAGE_WARNING |
            GST_MESSAGE_INFO );
    if( p_msg )
    {
        switch( GST_MESSAGE_TYPE( p_msg ) ){
        case GST_MESSAGE_EOS:
            /* for debugging purpose */
            msg_Warn( p_dec, "got unexpected eos" );
            break;
        /* First buffer received */
        case GST_MESSAGE_ASYNC_DONE:
            /* for debugging purpose */
            p_sys->b_prerolled = true;
            msg_Dbg( p_dec, "Pipeline is prerolled" );
            break;
        default:
            p_dec->b_error = default_msg_handler( p_dec, p_msg );
            if( p_dec->b_error )
            {
                gst_message_unref( p_msg );
                goto done;
            }
            break;
        }
        gst_message_unref( p_msg );
    }

    /* Look for any output buffers in the queue */
    if( gst_atomic_queue_peek( p_sys->p_que ) )
    {
        GstBuffer *p_buf = GST_BUFFER_CAST(
                gst_atomic_queue_pop( p_sys->p_que ));
        GstMemory *p_mem;

        if(( p_mem = gst_buffer_peek_memory( p_buf, 0 )) &&
            GST_IS_VLC_PICTURE_PLANE_ALLOCATOR( p_mem->allocator ))
        {
            p_pic = picture_Hold(( (GstVlcPicturePlane*) p_mem )->p_pic );
        }
        else
        {
            GstVideoFrame frame;

            /* Get a new picture */
            p_pic = decoder_NewPicture( p_dec );
            if( !p_pic )
                goto done;

            if( unlikely( !gst_video_frame_map( &frame,
                            &p_sys->vinfo, p_buf, GST_MAP_READ ) ) )
            {
                msg_Err( p_dec, "failed to map gst video frame" );
                gst_buffer_unref( p_buf );
                p_dec->b_error = true;
                goto done;
            }

            gst_CopyPicture( p_pic, &frame );
            gst_video_frame_unmap( &frame );
        }

        if( likely( GST_BUFFER_PTS_IS_VALID( p_buf ) ) )
            p_pic->date = gst_util_uint64_scale(
                GST_BUFFER_PTS( p_buf ), GST_MSECOND, GST_SECOND );
        else
            msg_Warn( p_dec, "Gst Buffer has no timestamp" );

        gst_buffer_unref( p_buf );
    }

done:
    *pp_block = NULL;
    return p_pic;
}
Example #11
0
static GstElement *
gst_auto_audio_sink_find_best (GstAutoAudioSink * sink)
{
  GList *list, *item;
  GstElement *choice = NULL;
  GstMessage *message = NULL;
  GSList *errors = NULL;
  GstBus *bus = gst_bus_new ();
  GstPad *el_pad = NULL;
  GstCaps *el_caps = NULL;
  gboolean no_match = TRUE;

  list = gst_registry_feature_filter (gst_registry_get (),
      (GstPluginFeatureFilter) gst_auto_audio_sink_factory_filter, FALSE, sink);
  list = g_list_sort (list, (GCompareFunc) gst_auto_audio_sink_compare_ranks);

  /* We don't treat sound server sinks special. Our policy is that sound
   * server sinks that have a rank must not auto-spawn a daemon under any
   * circumstances, so there's nothing for us to worry about here */
  GST_LOG_OBJECT (sink, "Trying to find usable audio devices ...");

  for (item = list; item != NULL; item = item->next) {
    GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
    GstElement *el;

    if ((el = gst_auto_audio_sink_create_element_with_pretty_name (sink, f))) {
      GstStateChangeReturn ret;

      GST_DEBUG_OBJECT (sink, "Testing %s", GST_OBJECT_NAME (f));

      /* If autoaudiosink has been provided with filter caps,
       * accept only sinks that match with the filter caps */
      if (sink->filter_caps) {
        el_pad = gst_element_get_static_pad (GST_ELEMENT (el), "sink");
        el_caps = gst_pad_query_caps (el_pad, NULL);
        gst_object_unref (el_pad);
        GST_DEBUG_OBJECT (sink,
            "Checking caps: %" GST_PTR_FORMAT " vs. %" GST_PTR_FORMAT,
            sink->filter_caps, el_caps);
        no_match = !gst_caps_can_intersect (sink->filter_caps, el_caps);
        gst_caps_unref (el_caps);

        if (no_match) {
          GST_DEBUG_OBJECT (sink, "Incompatible caps");
          gst_object_unref (el);
          continue;
        } else {
          GST_DEBUG_OBJECT (sink, "Found compatible caps");
        }
      }

      gst_element_set_bus (el, bus);
      ret = gst_element_set_state (el, GST_STATE_READY);
      if (ret == GST_STATE_CHANGE_SUCCESS) {
        GST_DEBUG_OBJECT (sink, "This worked!");
        choice = el;
        break;
      }

      /* collect all error messages */
      while ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR))) {
        GST_DEBUG_OBJECT (sink, "error message %" GST_PTR_FORMAT, message);
        errors = g_slist_append (errors, message);
      }

      gst_element_set_state (el, GST_STATE_NULL);
      gst_object_unref (el);
    }
  }

  GST_DEBUG_OBJECT (sink, "done trying");
  if (!choice) {
    if (errors) {
      /* FIXME: we forward the first error for now; but later on it might make
       * sense to actually analyse them */
      gst_message_ref (GST_MESSAGE (errors->data));
      GST_DEBUG_OBJECT (sink, "reposting message %p", errors->data);
      gst_element_post_message (GST_ELEMENT (sink), GST_MESSAGE (errors->data));
    } else {
      /* send warning message to application and use a fakesink */
      GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
          ("Failed to find a usable audio sink"));
      choice = gst_element_factory_make ("fakesink", "fake-audio-sink");
      if (g_object_class_find_property (G_OBJECT_GET_CLASS (choice), "sync"))
        g_object_set (choice, "sync", TRUE, NULL);
      gst_element_set_state (choice, GST_STATE_READY);
    }
  }
  gst_object_unref (bus);
  gst_plugin_feature_list_free (list);
  g_slist_foreach (errors, (GFunc) gst_mini_object_unref, NULL);
  g_slist_free (errors);

  return choice;
}
Example #12
0
int
main (int argc, char *argv[])
{
  GstNetClientInternalClock *clock;
  GstBus *bus;
  GIOChannel *channel;
  GIOStatus status;
  GError *error = NULL;
  GOptionContext *context;
  gchar *line;
  int ret = 1;

  context = g_option_context_new (NULL);
  g_option_context_add_main_entries (context, entries, NULL);
  g_option_context_add_group (context, gst_init_get_option_group ());

  if (!g_option_context_parse (context, &argc, &argv, &error)) {
    g_print ("Failed to parse options: %s\n\n", error->message);
    g_error_free (error);
    return 1;
  }

  if (input) {
    if (!(channel = g_io_channel_new_file (input, "r", NULL))) {
      g_print ("Could not read input file: %s\n", input);
      return 1;
    }
  } else {
    if (!(channel = g_io_channel_unix_new (0))) {
      g_print ("Could not read stdin");
      return 1;
    }
  }

  clock = g_object_new (GST_TYPE_NET_CLIENT_INTERNAL_CLOCK, NULL);
  bus = gst_bus_new ();

  /* FIXME: Find a way to do this without touching the structure internals */
  if (rtt_limit)
    clock->roundtrip_limit = rtt_limit * GST_MSECOND;
  clock->busses = g_list_prepend (clock->busses, bus);

  while ((status = g_io_channel_read_line (channel, &line, NULL, NULL,
              &error)) == G_IO_STATUS_NORMAL) {
    GstClockTime local_1, local_2, remote_1, remote_2;
    GstMessage *message;

    if (sscanf (line, "%" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT " %"
            G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, &local_1, &remote_1,
            &remote_2, &local_2) != 4) {
      g_print ("Failed to get local/remote time values from: %s\n", line);
      goto done;
    }

    if (debug)
      g_print ("%s", line);

    gst_net_client_internal_clock_observe_times (clock, local_1, remote_1,
        remote_2, local_2);

    g_free (line);

    if ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT))) {
      const GstStructure *st;
      gchar *str;

      st = gst_message_get_structure (message);
      str = gst_structure_to_string (st);

      g_print ("%s\n", str);

      g_free (str);
      gst_message_unref (message);
    }
  }

  if (status == G_IO_CHANNEL_ERROR) {
    g_print ("Error reading file: %s\n", error->message);
    g_error_free (error);
    goto done;
  }

  g_io_channel_unref (channel);
  g_free (input);
  gst_object_unref (bus);

  ret = 0;

done:
  return ret;
}