Example #1
0
gboolean
shmdata_base_reader_reset_time (GstPad *pad,
                                GstMiniObject * mini_obj,
                                gpointer user_data)
{

    shmdata_base_reader_t *context = (shmdata_base_reader_t *) user_data;
    if (GST_IS_EVENT (mini_obj))
    {
        //g_debug ("EVENT %s", GST_EVENT_TYPE_NAME (GST_EVENT_CAST(mini_obj)));
    }
    else if (GST_IS_BUFFER (mini_obj))
    {
        GstBuffer *buffer = GST_BUFFER_CAST (mini_obj);
        /* g_debug ("shmdata writer data frame (%p), data size %d, timestamp %llu, caps %s", */
        /* 	       GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), */
        /* 	       GST_TIME_AS_MSECONDS (GST_BUFFER_TIMESTAMP (buffer)), */
        /* 	       gst_caps_to_string (GST_BUFFER_CAPS (buffer))); */
        if (context->timereset_)
        {
            context->timeshift_ = GST_BUFFER_TIMESTAMP (buffer);
            context->timereset_ = FALSE;
        }
        GST_BUFFER_TIMESTAMP (buffer) =
            GST_BUFFER_TIMESTAMP (buffer) - context->timeshift_;
    }
    else if (GST_IS_MESSAGE (mini_obj))
    {
    }

    return TRUE;
}
/**
 * gst_is_missing_plugin_message:
 * @msg: a #GstMessage
 *
 * Checks whether @msg is a missing plugins message.
 *
 * Returns: %TRUE if @msg is a missing-plugins message, otherwise %FALSE.
 */
gboolean
gst_is_missing_plugin_message (GstMessage * msg)
{
  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (GST_IS_MESSAGE (msg), FALSE);

  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT || msg->structure == NULL)
    return FALSE;

  return gst_structure_has_name (msg->structure, "missing-plugin");
}
Example #3
0
/**
 * gst_bus_post:
 * @bus: a #GstBus to post on
 * @message: The #GstMessage to post
 *
 * Post a message on the given bus. Ownership of the message
 * is taken by the bus.
 *
 * Returns: TRUE if the message could be posted, FALSE if the bus is flushing.
 *
 * MT safe.
 */
gboolean
gst_bus_post (GstBus * bus, GstMessage * message)
{
  GstBusSyncReply reply = GST_BUS_PASS;
  GstBusSyncHandler handler;
  gboolean emit_sync_message;
  gpointer handler_data;

  g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
  g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);

  GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %s, %" GST_PTR_FORMAT
      " from source %" GST_PTR_FORMAT,
      message, GST_MESSAGE_TYPE_NAME (message), message->structure,
      message->src);

  GST_OBJECT_LOCK (bus);
  /* check if the bus is flushing */
  if (GST_OBJECT_FLAG_IS_SET (bus, GST_BUS_FLUSHING))
    goto is_flushing;

  handler = bus->sync_handler;
  handler_data = bus->sync_handler_data;
  emit_sync_message = bus->priv->num_sync_message_emitters > 0;
  GST_OBJECT_UNLOCK (bus);

  /* first call the sync handler if it is installed */
  if (handler)
    reply = handler (bus, message, handler_data);

  /* emit sync-message if requested to do so via
     gst_bus_enable_sync_message_emission. terrible but effective */
  if (emit_sync_message && reply != GST_BUS_DROP
      && handler != gst_bus_sync_signal_handler)
    gst_bus_sync_signal_handler (bus, message, NULL);

  /* now see what we should do with the message */
  switch (reply) {
    case GST_BUS_DROP:
      /* drop the message */
      GST_DEBUG_OBJECT (bus, "[msg %p] dropped", message);
      break;
    case GST_BUS_PASS:
      /* pass the message to the async queue, refcount passed in the queue */
      GST_DEBUG_OBJECT (bus, "[msg %p] pushing on async queue", message);
      g_mutex_lock (bus->queue_lock);
      g_queue_push_tail (bus->queue, message);
      g_cond_broadcast (bus->priv->queue_cond);
      g_mutex_unlock (bus->queue_lock);
      GST_DEBUG_OBJECT (bus, "[msg %p] pushed on async queue", message);

      gst_bus_wakeup_main_context (bus);

      break;
    case GST_BUS_ASYNC:
    {
      /* async delivery, we need a mutex and a cond to block
       * on */
      GMutex *lock = g_mutex_new ();
      GCond *cond = g_cond_new ();

      GST_MESSAGE_COND (message) = cond;
      GST_MESSAGE_GET_LOCK (message) = lock;

      GST_DEBUG_OBJECT (bus, "[msg %p] waiting for async delivery", message);

      /* now we lock the message mutex, send the message to the async
       * queue. When the message is handled by the app and destroyed,
       * the cond will be signalled and we can continue */
      g_mutex_lock (lock);
      g_mutex_lock (bus->queue_lock);
      g_queue_push_tail (bus->queue, message);
      g_cond_broadcast (bus->priv->queue_cond);
      g_mutex_unlock (bus->queue_lock);

      gst_bus_wakeup_main_context (bus);

      /* now block till the message is freed */
      g_cond_wait (cond, lock);
      g_mutex_unlock (lock);

      GST_DEBUG_OBJECT (bus, "[msg %p] delivered asynchronously", message);

      g_mutex_free (lock);
      g_cond_free (cond);
      break;
    }
    default:
      g_warning ("invalid return from bus sync handler");
      break;
  }
  return TRUE;

  /* ERRORS */
is_flushing:
  {
    GST_DEBUG_OBJECT (bus, "bus is flushing");
    gst_message_unref (message);
    GST_OBJECT_UNLOCK (bus);

    return FALSE;
  }
}
Example #4
0
/**
 * gst_bus_post:
 * @bus: a #GstBus to post on
 * @message: (transfer full): the #GstMessage to post
 *
 * Post a message on the given bus. Ownership of the message
 * is taken by the bus.
 *
 * Returns: %TRUE if the message could be posted, %FALSE if the bus is flushing.
 *
 * MT safe.
 */
gboolean
gst_bus_post (GstBus * bus, GstMessage * message)
{
  GstBusSyncReply reply = GST_BUS_PASS;
  GstBusSyncHandler handler;
  gboolean emit_sync_message;
  gpointer handler_data;

  g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
  g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);

  GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus %" GST_PTR_FORMAT, message,
      message);

  /* check we didn't accidentally add a public flag that maps to same value */
  g_assert (!GST_MINI_OBJECT_FLAG_IS_SET (message,
          GST_MESSAGE_FLAG_ASYNC_DELIVERY));

  GST_OBJECT_LOCK (bus);
  /* check if the bus is flushing */
  if (GST_OBJECT_FLAG_IS_SET (bus, GST_BUS_FLUSHING))
    goto is_flushing;

  handler = bus->priv->sync_handler;
  handler_data = bus->priv->sync_handler_data;
  emit_sync_message = bus->priv->num_sync_message_emitters > 0;
  GST_OBJECT_UNLOCK (bus);

  /* first call the sync handler if it is installed */
  if (handler)
    reply = handler (bus, message, handler_data);

  /* emit sync-message if requested to do so via
     gst_bus_enable_sync_message_emission. terrible but effective */
  if (emit_sync_message && reply != GST_BUS_DROP
      && handler != gst_bus_sync_signal_handler)
    gst_bus_sync_signal_handler (bus, message, NULL);

  /* If this is a bus without async message delivery
   * always drop the message */
  if (!bus->priv->poll)
    reply = GST_BUS_DROP;

  /* now see what we should do with the message */
  switch (reply) {
    case GST_BUS_DROP:
      /* drop the message */
      GST_DEBUG_OBJECT (bus, "[msg %p] dropped", message);
      break;
    case GST_BUS_PASS:
      /* pass the message to the async queue, refcount passed in the queue */
      GST_DEBUG_OBJECT (bus, "[msg %p] pushing on async queue", message);
      gst_atomic_queue_push (bus->priv->queue, message);
      gst_poll_write_control (bus->priv->poll);
      GST_DEBUG_OBJECT (bus, "[msg %p] pushed on async queue", message);

      break;
    case GST_BUS_ASYNC:
    {
      /* async delivery, we need a mutex and a cond to block
       * on */
      GCond *cond = GST_MESSAGE_GET_COND (message);
      GMutex *lock = GST_MESSAGE_GET_LOCK (message);

      g_cond_init (cond);
      g_mutex_init (lock);

      GST_MINI_OBJECT_FLAG_SET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY);

      GST_DEBUG_OBJECT (bus, "[msg %p] waiting for async delivery", message);

      /* now we lock the message mutex, send the message to the async
       * queue. When the message is handled by the app and destroyed,
       * the cond will be signalled and we can continue */
      g_mutex_lock (lock);

      gst_atomic_queue_push (bus->priv->queue, message);
      gst_poll_write_control (bus->priv->poll);

      /* now block till the message is freed */
      g_cond_wait (cond, lock);

      /* we acquired a new ref from gst_message_dispose() so we can clean up */
      g_mutex_unlock (lock);

      GST_DEBUG_OBJECT (bus, "[msg %p] delivered asynchronously", message);

      GST_MINI_OBJECT_FLAG_UNSET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY);

      g_mutex_clear (lock);
      g_cond_clear (cond);

      gst_message_unref (message);
      break;
    }
    default:
      g_warning ("invalid return from bus sync handler");
      break;
  }
  return TRUE;

  /* ERRORS */
is_flushing:
  {
    GST_DEBUG_OBJECT (bus, "bus is flushing");
    GST_OBJECT_UNLOCK (bus);
    gst_message_unref (message);

    return FALSE;
  }
}
void __mm_player_streaming_buffering(mm_player_streaming_t* streamer, GstMessage *buffering_msg)
{
	GstBufferingMode mode = GST_BUFFERING_STREAM;
	gint byte_in_rate = 0;
	gint byte_out_rate = 0;
	gint64 buffering_left = -1;
	gdouble buffering_time = DEFAULT_BUFFERING_TIME;
	gdouble low_percent = 0.0;
	gdouble high_percent = 0.0;
	guint high_percent_byte = 0;
	gint buffer_percent = 0;
	guint buffer_criteria = 0;

	return_if_fail ( streamer );
	return_if_fail ( buffering_msg );
	return_if_fail ( GST_IS_MESSAGE ( buffering_msg ) );
	return_if_fail ( GST_MESSAGE_TYPE ( buffering_msg ) == GST_MESSAGE_BUFFERING );

	/* update when buffering has started. */
	if ( !streamer->is_buffering )
	{
		debug_log ( "buffering has started.\n" );

		streamer->is_buffering = TRUE;
		streamer->buffering_percent = -1;
		streamer->need_update = TRUE;
	}

	/* update buffer percent */
	gst_message_parse_buffering ( buffering_msg, &buffer_percent );

	if ( streamer->buffering_percent < buffer_percent )
	{
		debug_log ( "buffering %d%%....\n", buffer_percent );
		streamer->buffering_percent = buffer_percent;
	}

	if ( streamer->buffering_percent == MAX_BUFFER_PERCENT )
	{
		debug_log ( "buffering had done.\n" );
		streamer->is_buffering = FALSE;
	}

	if (!streamer->need_update)
	{
		debug_log ( "don't need to update buffering stats during buffering.\n" );
		return;
	}

        /* Note : Parse the buffering message to get the in/out throughput.
         *     avg_in is the network throughput and avg_out is the consumed throughtput by the linkded element.
         */
	gst_message_parse_buffering_stats ( buffering_msg, &mode, &byte_in_rate, &byte_out_rate, &buffering_left );

	if (streamer->buffer_max_bitrate > 0)
	{
		buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate);
		byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate /3);
	}
	else if (streamer->buffer_avg_bitrate > 0)
	{
		buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate * 3);
		byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate);
	}

	debug_log ( "in rate is %d, out rate is %d (bytes/sec).\n", byte_in_rate, byte_out_rate );

	if ( byte_in_rate > 0  &&  byte_out_rate > 0)
		buffering_time =  byte_out_rate / byte_in_rate;
	else if (byte_in_rate <= 0 && byte_out_rate > 0)
		buffering_time = MAX_BUFFERING_TIME;
	else
		buffering_time = DEFAULT_BUFFERING_TIME;

	streaming_set_buffering_time(streamer, buffering_time);

	/* calculate buffer low/high percent */
	low_percent = DEFAULT_BUFFER_LOW_PERCENT;

	if ( buffer_criteria > 0 )
	{
		high_percent_byte = buffer_criteria * streamer->buffering_time;
		high_percent = ( (gdouble)high_percent_byte * 100.0 )  / (gdouble)streamer->buffer_size;
	}
	else
	{
		high_percent_byte = streamer->buffer_high_percent * streamer->buffer_size / 100;
		high_percent= streamer->buffer_high_percent;
	}

	if ( streamer->buffer_size < high_percent_byte )
	{
		debug_log ( "buffer size[%d bytes] is smaller than high threshold[%d bytes]. update it. \n",
			streamer->buffer_size, high_percent_byte );

		streaming_set_buffer_size(streamer, high_percent_byte * 1.1);
	}

	streaming_set_buffer_percent(streamer, low_percent, high_percent);

	streamer->need_update = FALSE;

	return;
}