예제 #1
0
/**
 * @internal
 */
static gboolean
xmms_output_format_set (xmms_output_t *output, xmms_stream_type_t *fmt)
{
	g_return_val_if_fail (output, FALSE);
	g_return_val_if_fail (fmt, FALSE);

	XMMS_DBG ("Setting format!");

	if (!xmms_output_plugin_format_set_always (output->plugin)) {
		if (output->format && xmms_stream_type_match (output->format, fmt)) {
			XMMS_DBG ("audio formats are equal, not updating");
			return TRUE;
		}

		xmms_object_unref (output->format);
		xmms_object_ref (fmt);
		output->format = fmt;
		return xmms_output_plugin_method_format_set (output->plugin, output, output->format);
	} else {
		if (output->format && !xmms_stream_type_match (output->format, fmt)) {
			xmms_object_unref (output->format);
			xmms_object_ref (fmt);
			output->format = fmt;
		}
		if (!output->format) {
			xmms_object_unref (output->format);
			xmms_object_ref (fmt);
			output->format = fmt;
		}
		return xmms_output_plugin_method_format_set (output->plugin, output, output->format);
	}
}
예제 #2
0
파일: playlist.c 프로젝트: dsheeler/xmms2
/**
 * Initializes a new xmms_playlist_t.
 */
xmms_playlist_t *
xmms_playlist_init (xmms_medialib_t *medialib, xmms_coll_dag_t *colldag)
{
	xmms_playlist_t *ret;
	xmms_config_property_t *val;

	ret = xmms_object_new (xmms_playlist_t, xmms_playlist_destroy);
	ret->mutex = g_mutex_new ();

	xmms_playlist_register_ipc_commands (XMMS_OBJECT (ret));

	val = xmms_config_property_register ("playlist.repeat_one", "0",
	                                     on_playlist_r_one_changed, ret);
	ret->repeat_one = xmms_config_property_get_int (val);

	val = xmms_config_property_register ("playlist.repeat_all", "0",
	                                  on_playlist_r_all_changed, ret);
	ret->repeat_all = xmms_config_property_get_int (val);

	xmms_object_ref (medialib);
	ret->medialib = medialib;

	xmms_object_ref (colldag);
	ret->colldag = colldag;

	xmms_object_connect (XMMS_OBJECT (ret->medialib),
	                     XMMS_IPC_SIGNAL_MEDIALIB_ENTRY_REMOVED,
	                     on_medialib_entry_removed, ret);

	xmms_object_connect (XMMS_OBJECT (ret->colldag),
	                     XMMS_IPC_SIGNAL_COLLECTION_CHANGED,
	                     on_collection_changed, ret);

	return ret;
}
예제 #3
0
/**
 * Allocate a new #xmms_output_t
 */
xmms_output_t *
xmms_output_new (xmms_output_plugin_t *plugin, xmms_playlist_t *playlist, xmms_medialib_t *medialib)
{
	xmms_output_t *output;
	xmms_config_property_t *prop;
	gint size;

	g_return_val_if_fail (playlist, NULL);

	XMMS_DBG ("Trying to open output");

	output = xmms_object_new (xmms_output_t, xmms_output_destroy);

	xmms_object_ref (playlist);
	output->playlist = playlist;

	xmms_object_ref (medialib);
	output->medialib = medialib;

	g_mutex_init (&output->status_mutex);
	g_mutex_init (&output->playtime_mutex);

	prop = xmms_config_property_register ("output.buffersize", "32768", NULL, NULL);
	size = xmms_config_property_get_int (prop);
	XMMS_DBG ("Using buffersize %d", size);

	g_mutex_init (&output->filler_mutex);
	output->filler_state = FILLER_STOP;
	g_cond_init (&output->filler_state_cond);
	output->filler_buffer = xmms_ringbuf_new (size);
	output->filler_thread = g_thread_new ("x2 out filler", xmms_output_filler, output);

	xmms_config_property_register ("output.flush_on_pause", "1", NULL, NULL);

	xmms_playback_register_ipc_commands (XMMS_OBJECT (output));

	output->status = XMMS_PLAYBACK_STATUS_STOP;

	if (plugin) {
		if (!set_plugin (output, plugin)) {
			xmms_log_error ("Could not initialize output plugin");
		}
	} else {
		xmms_log_error ("initalized output without a plugin, please fix!");
	}



	return output;
}
예제 #4
0
xmms_playlist_updater_t *
xmms_playlist_updater_init (xmms_playlist_t *playlist)
{
	xmms_playlist_updater_t *updater;

	updater = xmms_object_new (xmms_playlist_updater_t,
	                           xmms_playlist_updater_destroy);

	updater->cond = g_cond_new ();
	updater->mutex = g_mutex_new ();

	xmms_object_ref (playlist);
	updater->playlist = playlist;

	updater->updating = NULL;
	updater->stack = NULL;

	xmms_object_connect (XMMS_OBJECT (playlist),
	                     XMMS_IPC_SIGNAL_COLLECTION_CHANGED,
	                     xmms_playlist_updater_need_update, updater);

	xmms_object_connect (XMMS_OBJECT (playlist),
	                     XMMS_IPC_SIGNAL_PLAYLIST_CHANGED,
	                     xmms_playlist_updater_need_update, updater);

	xmms_object_connect (XMMS_OBJECT (playlist),
	                     XMMS_IPC_SIGNAL_PLAYLIST_CURRENT_POS,
	                     xmms_playlist_updater_need_update, updater);

	xmms_playlist_updater_start (updater);

	return updater;
}
예제 #5
0
xmms_xform_t *
xmms_xform_new (xmms_xform_plugin_t *plugin, xmms_xform_t *prev,
                xmms_medialib_t *medialib, xmms_medialib_entry_t entry,
                GList *goal_hints)
{
	xmms_xform_t *xform;

	xform = xmms_object_new (xmms_xform_t, xmms_xform_destroy);

	xmms_object_ref (plugin);
	xform->plugin = plugin;
	xform->entry = entry;
	xform->medialib = medialib;
	xform->goal_hints = goal_hints;
	xform->lr.bufend = &xform->lr.buf[0];

	if (prev) {
		xmms_object_ref (prev);
		xform->prev = prev;
	}

	xform->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
	                                         g_free,
	                                         (GDestroyNotify) xmmsv_unref);

	xform->privdata = g_hash_table_new_full (g_str_hash, g_str_equal,
	                                         g_free,
	                                         (GDestroyNotify) xmmsv_unref);
	xform->hotspots = g_queue_new ();

	if (plugin && entry) {
		if (!xmms_xform_plugin_init (xform->plugin, xform)) {
			xmms_object_unref (xform);
			return NULL;
		}
		xform->inited = TRUE;
		g_return_val_if_fail (xform->out_type, NULL);
	}

	xform->buffer = g_malloc (READ_CHUNK);
	xform->buffersize = READ_CHUNK;

	return xform;
}
예제 #6
0
static gboolean
xmms_plugin_find_foreach (xmms_plugin_t *plugin, gpointer udata)
{
	xmms_plugin_find_foreach_data_t *data = udata;

	if (!g_ascii_strcasecmp (plugin->shortname, data->name)) {
		xmms_object_ref (plugin);
		data->plugin = plugin;
		return FALSE;
	}
	return TRUE;
}
예제 #7
0
static xmms_medialib_session_t *
xmms_medialib_session_begin_internal (xmms_medialib_t *medialib,
                                      s4_transaction_flag_t flags)
{
	xmms_medialib_session_t *ret = g_new0 (xmms_medialib_session_t, 1);

	xmms_object_ref (medialib);
	ret->medialib = medialib;

	s4_t *s4 = xmms_medialib_get_database_backend (medialib);
	ret->trans = s4_begin (s4, flags);

	return ret;
}
예제 #8
0
/**
 * Initialize the Vis module.
 */
xmms_visualization_t *
xmms_visualization_new (xmms_output_t *output)
{
	vis = xmms_object_new (xmms_visualization_t, xmms_visualization_destroy);
	g_mutex_init (&vis->clientlock);
	vis->clientc = 0;
	vis->output = output;

	xmms_object_ref (output);

	xmms_visualization_register_ipc_commands (XMMS_OBJECT (vis));

	xmms_socket_invalidate (&vis->socket);

	return vis;
}
예제 #9
0
파일: object.c 프로젝트: dsheeler/xmms2
xmms_object_t *
__int_xmms_object_new (gint size, xmms_object_destroy_func_t destfunc)
{
	xmms_object_t *ret;

	ret = g_malloc0 (size);
	ret->destroy_func = destfunc;
	ret->id = XMMS_OBJECT_MID;

	ret->mutex = g_mutex_new ();

	/* don't create the trees for the signals and the commands yet.
	 * instead we instantiate those when we need them the first
	 * time.
	 */

	xmms_object_ref (ret);

	return ret;
}
예제 #10
0
void
xmms_xform_outdata_type_copy (xmms_xform_t *xform)
{
	xmms_object_ref (xform->prev->out_type);
	xform->out_type = xform->prev->out_type;
}
예제 #11
0
void
xmms_xform_outdata_type_set (xmms_xform_t *xform, xmms_stream_type_t *type)
{
	xmms_object_ref (type);
	xform->out_type = type;
}
예제 #12
0
static void *
xmms_output_filler (void *arg)
{
	xmms_output_t *output = (xmms_output_t *)arg;
	xmms_xform_t *chain = NULL;
	gboolean last_was_kill = FALSE;
	char buf[4096];
	xmms_error_t err;
	gint ret;

	xmms_error_reset (&err);

	g_mutex_lock (output->filler_mutex);
	while (output->filler_state != FILLER_QUIT) {
		if (output->filler_state == FILLER_STOP) {
			if (chain) {
				xmms_object_unref (chain);
				chain = NULL;
			}
			xmms_ringbuf_set_eos (output->filler_buffer, TRUE);
			g_cond_wait (output->filler_state_cond, output->filler_mutex);
			last_was_kill = FALSE;
			continue;
		}
		if (output->filler_state == FILLER_KILL) {
			if (chain) {
				xmms_object_unref (chain);
				chain = NULL;
				output->filler_state = FILLER_RUN;
				last_was_kill = TRUE;
			} else {
				output->filler_state = FILLER_STOP;
			}
			continue;
		}
		if (output->filler_state == FILLER_SEEK) {
			if (!chain) {
				XMMS_DBG ("Seek without chain, ignoring..");
				output->filler_state = FILLER_STOP;
				continue;
			}

			ret = xmms_xform_this_seek (chain, output->filler_seek, XMMS_XFORM_SEEK_SET, &err);
			if (ret == -1) {
				XMMS_DBG ("Seeking failed: %s", xmms_error_message_get (&err));
			} else {
				XMMS_DBG ("Seek ok! %d", ret);

				output->filler_skip = output->filler_seek - ret;
				if (output->filler_skip < 0) {
					XMMS_DBG ("Seeked %d samples too far! Updating position...",
					          -output->filler_skip);

					output->filler_skip = 0;
					output->filler_seek = ret;
				}

				xmms_ringbuf_clear (output->filler_buffer);
				xmms_ringbuf_hotspot_set (output->filler_buffer, seek_done, NULL, output);
			}
			output->filler_state = FILLER_RUN;
		}

		if (!chain) {
			xmms_medialib_entry_t entry;
			xmms_output_song_changed_arg_t *arg;
			xmms_medialib_session_t *session;

			g_mutex_unlock (output->filler_mutex);

			entry = xmms_playlist_current_entry (output->playlist);
			if (!entry) {
				XMMS_DBG ("No entry from playlist!");
				output->filler_state = FILLER_STOP;
				g_mutex_lock (output->filler_mutex);
				continue;
			}

			chain = xmms_xform_chain_setup (entry, output->format_list, FALSE);
			if (!chain) {
				session = xmms_medialib_begin_write ();
				if (xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS) == XMMS_MEDIALIB_ENTRY_STATUS_NEW) {
					xmms_medialib_end (session);
					xmms_medialib_entry_remove (entry);
				} else {
					xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE);
					xmms_medialib_entry_send_update (entry);
					xmms_medialib_end (session);
				}

				if (!xmms_playlist_advance (output->playlist)) {
					XMMS_DBG ("End of playlist");
					output->filler_state = FILLER_STOP;
				}
				g_mutex_lock (output->filler_mutex);
				continue;
			}

			arg = g_new0 (xmms_output_song_changed_arg_t, 1);
			arg->output = output;
			arg->chain = chain;
			arg->flush = last_was_kill;
			xmms_object_ref (chain);

			last_was_kill = FALSE;

			g_mutex_lock (output->filler_mutex);
			xmms_ringbuf_hotspot_set (output->filler_buffer, song_changed, song_changed_arg_free, arg);
		}

		xmms_ringbuf_wait_free (output->filler_buffer, sizeof (buf), output->filler_mutex);

		if (output->filler_state != FILLER_RUN) {
			XMMS_DBG ("State changed while waiting...");
			continue;
		}
		g_mutex_unlock (output->filler_mutex);

		ret = xmms_xform_this_read (chain, buf, sizeof (buf), &err);

		g_mutex_lock (output->filler_mutex);

		if (ret > 0) {
			gint skip = MIN (ret, output->toskip);

			output->toskip -= skip;
			if (ret > skip) {
				xmms_ringbuf_write_wait (output->filler_buffer,
				                         buf + skip,
				                         ret - skip,
				                         output->filler_mutex);
			}
		} else {
			if (ret == -1) {
				/* print error */
				xmms_error_reset (&err);
			}
			xmms_object_unref (chain);
			chain = NULL;
			if (!xmms_playlist_advance (output->playlist)) {
				XMMS_DBG ("End of playlist");
				output->filler_state = FILLER_STOP;
			}
		}

	}
	g_mutex_unlock (output->filler_mutex);
	return NULL;
}