gboolean
MediaPluginGStreamer010::processGSTEvents(GstBus     *bus,
					  GstMessage *message)
{
	if (!message) 
		return TRUE; // shield against GStreamer bug

	if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
	    GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
	{
		DEBUGMSG("Got GST message type: %s",
			LLGST_MESSAGE_TYPE_NAME (message));
	}
	else
	{
		// TODO: grok 'duration' message type
		DEBUGMSG("Got GST message type: %s",
			 LLGST_MESSAGE_TYPE_NAME (message));
	}

	switch (GST_MESSAGE_TYPE (message)) {
	case GST_MESSAGE_BUFFERING: {
		// NEEDS GST 0.10.11+
		if (llgst_message_parse_buffering)
		{
			gint percent = 0;
			llgst_message_parse_buffering(message, &percent);
			DEBUGMSG("GST buffering: %d%%", percent);
		}
		break;
	}
	case GST_MESSAGE_STATE_CHANGED: {
		GstState old_state;
		GstState new_state;
		GstState pending_state;
		llgst_message_parse_state_changed(message,
						&old_state,
						&new_state,
						&pending_state);
#ifdef LL_GST_REPORT_STATE_CHANGES
		// not generally very useful, and rather spammy.
		DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s",
			 get_gst_state_name(old_state),
			 get_gst_state_name(new_state),
			 get_gst_state_name(pending_state));
#endif // LL_GST_REPORT_STATE_CHANGES

		switch (new_state) {
		case GST_STATE_VOID_PENDING:
			break;
		case GST_STATE_NULL:
			break;
		case GST_STATE_READY:
			setStatus(STATUS_LOADED);
			break;
		case GST_STATE_PAUSED:
			setStatus(STATUS_PAUSED);
			break;
		case GST_STATE_PLAYING:
			setStatus(STATUS_PLAYING);
			break;
		}
		break;
	}
	case GST_MESSAGE_ERROR: {
		GError *err = NULL;
		gchar *debug = NULL;

		llgst_message_parse_error (message, &err, &debug);
		WARNMSG("GST error: %s", err?err->message:"(unknown)");
		if (err)
			g_error_free (err);
		g_free (debug);

		mCommand = COMMAND_STOP;

		setStatus(STATUS_ERROR);

		break;
	}
	case GST_MESSAGE_INFO: {
		if (llgst_message_parse_info)
		{
			GError *err = NULL;
			gchar *debug = NULL;
			
			llgst_message_parse_info (message, &err, &debug);
			INFOMSG("GST info: %s", err?err->message:"(unknown)");
			if (err)
				g_error_free (err);
			g_free (debug);
		}
		break;
	}
	case GST_MESSAGE_WARNING: {
		GError *err = NULL;
		gchar *debug = NULL;

		llgst_message_parse_warning (message, &err, &debug);
		WARNMSG("GST warning: %s", err?err->message:"(unknown)");
		if (err)
			g_error_free (err);
		g_free (debug);

		break;
	}
	case GST_MESSAGE_EOS:
		/* end-of-stream */
		DEBUGMSG("GST end-of-stream.");
		if (mIsLooping)
		{
			DEBUGMSG("looping media...");
			double eos_pos_sec = 0.0F;
			bool got_eos_position = getTimePos(eos_pos_sec);

			if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC)
			{
				// if we know that the movie is really short, don't
				// loop it else it can easily become a time-hog
				// because of GStreamer spin-up overhead
				DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec);
				// inject a COMMAND_PAUSE
				mCommand = COMMAND_PAUSE;
			}
			else
			{
#undef LLGST_LOOP_BY_SEEKING
// loop with a stop-start instead of a seek, because it actually seems rather
// faster than seeking on remote streams.
#ifdef LLGST_LOOP_BY_SEEKING
				// first, try looping by an explicit rewind
				bool seeksuccess = seek(0.0);
				if (seeksuccess)
				{
					play(1.0);
				}
				else
#endif // LLGST_LOOP_BY_SEEKING
				{  // use clumsy stop-start to loop
					DEBUGMSG("didn't loop by rewinding - stopping and starting instead...");
					stop();
					play(1.0);
				}
			}
		}
		else // not a looping media
		{
			// inject a COMMAND_STOP
			mCommand = COMMAND_STOP;
		}
		break;
	default:
		/* unhandled message */
		break;
	}

	/* we want to be notified again the next time there is a message
	 * on the bus, so return true (false means we want to stop watching
	 * for messages on the bus and our callback should not be called again)
	 */
	return TRUE;
}
Exemple #2
0
static gboolean
my_bus_callback (GstBus     *bus,
		 GstMessage *message,
		 gpointer    data)
{
	if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
	    GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
	{
		llinfos << "Got GST message type: "
			<< LLGST_MESSAGE_TYPE_NAME (message)
			<< llendl;
	}
	else
	{
		lldebugs << "Got GST message type: "
			 << LLGST_MESSAGE_TYPE_NAME (message)
			 << llendl;
	}

	LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data;

	switch (GST_MESSAGE_TYPE (message)) {
	case GST_MESSAGE_BUFFERING: {
		// NEEDS GST 0.10.11+
		if (llgst_message_parse_buffering)
		{
			gint percent = 0;
			llgst_message_parse_buffering(message, &percent);
			llinfos << "GST buffering: " << percent
				<< "%" << llendl;
			// ModeBuffering seems to do nothing except make
			// the UI worse
			/*if (percent < 100) impl->setCurrentMode(LLMediaImplGStreamer::ModeBuffering);*/
		}
		break;
	}
	case GST_MESSAGE_STATE_CHANGED: {
		GstState old_state;
		GstState new_state;
		GstState pending_state;
		llgst_message_parse_state_changed(message,
						&old_state,
						&new_state,
						&pending_state);
#ifdef LL_GST_REPORT_STATE_CHANGES
		// not generally very useful, and rather spammy.
		llinfos << "state change (old,<new>,pending): "
			<< get_gst_state_name(old_state) << ", <"
			<< get_gst_state_name(new_state) << ">, "
			<< get_gst_state_name(pending_state) <<
			llendl;
#endif // LL_GST_REPORT_STATE_CHANGES

		switch (new_state) {
		case GST_STATE_VOID_PENDING:
			impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
			break;
		case GST_STATE_NULL:
			impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
			break;
		case GST_STATE_READY:
			impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);
			break;
		case GST_STATE_PAUSED:
			impl->setCurrentMode(LLMediaImplGStreamer::ModePaused);
			break;
		case GST_STATE_PLAYING:
			impl->setCurrentMode(LLMediaImplGStreamer::ModePlaying);
			break;
		}
		break;
	}
	case GST_MESSAGE_ERROR: {
		GError *err;
		gchar *debug;

		llgst_message_parse_error (message, &err, &debug);
		llinfos << "GST error: " << err->message << llendl;
		g_error_free (err);
		g_free (debug);

		impl->setCurrentMode(LLMediaImplGStreamer::ModeError);

		impl->stop();

		break;
	}
	case GST_MESSAGE_INFO: {
		if (llgst_message_parse_info)
		{
			GError *err;
			gchar *debug;
			
			llgst_message_parse_info (message, &err, &debug);
			llinfos << "GST info: " << err->message << llendl;
			g_error_free (err);
			g_free (debug);
		}
		break;
	}
	case GST_MESSAGE_WARNING: {
		GError *err;
		gchar *debug;

		llgst_message_parse_warning (message, &err, &debug);
		llinfos << "GST warning: " << err->message << llendl;
		g_error_free (err);
		g_free (debug);

		break;
	}
	case GST_MESSAGE_EOS:
		/* end-of-stream */
		llinfos << "GST EOS." << llendl;
		impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);//?
		impl->stop();
		break;
	default:
		/* unhandled message */
		break;
	}

	/* we want to be notified again the next time there is a message
	 * on the bus, so returning TRUE (FALSE means we want to stop watching
	 * for messages on the bus and our callback should not be called again)
	 */
	return TRUE;
}
Exemple #3
0
//static
gboolean
LLMediaImplGStreamer::bus_callback (GstBus     *bus,
				    GstMessage *message,
				    gpointer    data)
{
	if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
	    GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
	{
		DEBUGMSG("Got GST message type: %s",
			LLGST_MESSAGE_TYPE_NAME (message));
	}
	else
	{
		DEBUGMSG("Got GST message type: %s",
			 LLGST_MESSAGE_TYPE_NAME (message));
	}

	LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data;

	switch (GST_MESSAGE_TYPE (message)) {
	case GST_MESSAGE_BUFFERING: {
		// NEEDS GST 0.10.11+
		if (llgst_message_parse_buffering)
		{
			gint percent = 0;
			llgst_message_parse_buffering(message, &percent);
			DEBUGMSG("GST buffering: %d%%", percent);
			LLMediaEvent event( impl, percent );
			impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event );

		}
		break;
	}
	case GST_MESSAGE_STATE_CHANGED: {
		GstState old_state;
		GstState new_state;
		GstState pending_state;
		llgst_message_parse_state_changed(message,
						&old_state,
						&new_state,
						&pending_state);
#ifdef LL_GST_REPORT_STATE_CHANGES
		// not generally very useful, and rather spammy.
		DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s",
			 get_gst_state_name(old_state),
			 get_gst_state_name(new_state),
			 get_gst_state_name(pending_state));
#endif // LL_GST_REPORT_STATE_CHANGES

		switch (new_state) {
		case GST_STATE_VOID_PENDING:
			break;
		case GST_STATE_NULL:
			break;
		case GST_STATE_READY:
			break;
		case GST_STATE_PAUSED:
			break;
		case GST_STATE_PLAYING:
			LLMediaEvent event( impl, 100 );
			impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event );
			// emit an event to say that a media source was loaded
			LLMediaEvent event2( impl );
			impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 );
			break;
		}
		break;
	}
	case GST_MESSAGE_ERROR: {
		GError *err = NULL;
		gchar *debug = NULL;

		llgst_message_parse_error (message, &err, &debug);
		WARNMSG("GST error: %s", err->message);
		g_error_free (err);
		g_free (debug);

		impl->addCommand(LLMediaBase::COMMAND_STOP);

		break;
	}
	case GST_MESSAGE_INFO: {
		if (llgst_message_parse_info)
		{
			GError *err = NULL;
			gchar *debug = NULL;
			
			llgst_message_parse_info (message, &err, &debug);
			INFOMSG("GST info: %s", err->message);
			g_error_free (err);
			g_free (debug);
		}
		break;
	}
	case GST_MESSAGE_WARNING: {
		GError *err = NULL;
		gchar *debug = NULL;

		llgst_message_parse_warning (message, &err, &debug);
		WARNMSG("GST warning: %s", err->message);
		g_error_free (err);
		g_free (debug);

		break;
	}
	case GST_MESSAGE_EOS:
		/* end-of-stream */
		DEBUGMSG("GST end-of-stream.");
		if (impl->isLooping())
		{
			DEBUGMSG("looping media...");
			impl->stop();
			impl->play();
		}
		else
		{
			// inject a COMMAND_STOP
			impl->addCommand(LLMediaBase::COMMAND_STOP);
		}
		break;
	default:
		/* unhandled message */
		break;
	}

	/* we want to be notified again the next time there is a message
	 * on the bus, so return true (false means we want to stop watching
	 * for messages on the bus and our callback should not be called again)
	 */
	return TRUE;
}