示例#1
0
/**
 * Opens the input stream with input_stream_open(), and waits until
 * the stream gets ready.  If a decoder STOP command is received
 * during that, it cancels the operation (but does not close the
 * stream).
 *
 * Unlock the decoder before calling this function.
 *
 * @return an input_stream on success or if #DECODE_COMMAND_STOP is
 * received, NULL on error
 */
static struct input_stream *
decoder_input_stream_open(struct decoder_control *dc, const char *uri)
{
	GError *error = NULL;
	struct input_stream *is;

	is = input_stream_open(uri, &error);
	if (is == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}

		return NULL;
	}

	/* wait for the input stream to become ready; its metadata
	   will be available then */

	while (!is->ready &&
	       decoder_lock_get_command(dc) != DECODE_COMMAND_STOP) {
		int ret;

		ret = input_stream_buffer(is, &error);
		if (ret < 0) {
			input_stream_close(is);
			g_warning("%s", error->message);
			g_error_free(error);
			return NULL;
		}
	}

	return is;
}
static int
dump_input_stream(struct input_stream *is)
{
	GError *error = NULL;
	char buffer[4096];
	size_t num_read;
	ssize_t num_written;

	/* wait until the stream becomes ready */

	while (!is->ready) {
		int ret = input_stream_buffer(is, &error);
		if (ret < 0) {
			/* error */
			g_warning("%s", error->message);
			g_error_free(error);
			return 2;
		}

		if (ret == 0)
			/* nothing was buffered - wait */
			g_usleep(10000);
	}

	/* print meta data */

	if (is->mime != NULL)
		g_printerr("MIME type: %s\n", is->mime);

	/* read data and tags from the stream */

	while (!input_stream_eof(is)) {
		struct tag *tag = input_stream_tag(is);
		if (tag != NULL) {
			g_printerr("Received a tag:\n");
			tag_save(stderr, tag);
			tag_free(tag);
		}

		num_read = input_stream_read(is, buffer, sizeof(buffer),
					     &error);
		if (num_read == 0) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			}

			break;
		}

		num_written = write(1, buffer, num_read);
		if (num_written <= 0)
			break;
	}

	return 0;
}
/**
 * This is a wrapper for input_stream_buffer().  It assumes that the
 * decoder is currently locked, and temporarily unlocks it while
 * calling input_stream_buffer().  We shouldn't hold the lock during a
 * potentially blocking operation.
 */
static bool
decoder_input_buffer(struct decoder_control *dc, struct input_stream *is)
{
	GError *error = NULL;
	int ret;

	decoder_unlock(dc);
	ret = input_stream_buffer(is, &error);
	if (ret < 0) {
		g_warning("%s", error->message);
		g_error_free(error);
	}

	decoder_lock(dc);

	return ret > 0;
}
struct playlist_provider *
playlist_list_open_path(const char *path_fs)
{
	GError *error = NULL;
	const char *suffix;
	struct input_stream *is;
	struct playlist_provider *playlist;

	assert(path_fs != NULL);

	suffix = uri_get_suffix(path_fs);
	if (suffix == NULL || !playlist_suffix_supported(suffix))
		return NULL;

	is = input_stream_open(path_fs, &error);
	if (is == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}

		return NULL;
	}

	while (!is->ready) {
		int ret = input_stream_buffer(is, &error);
		if (ret < 0) {
			input_stream_close(is);
			g_warning("%s", error->message);
			g_error_free(error);
			return NULL;
		}
	}

	playlist = playlist_list_open_stream_suffix(is, suffix);
	if (playlist == NULL)
		input_stream_close(is);

	return playlist;
}