Ejemplo n.º 1
0
static struct playlist_provider *
playlist_list_open_stream_suffix(struct input_stream *is, const char *suffix)
{
	struct playlist_provider *playlist;

	assert(is != NULL);
	assert(suffix != NULL);

	for (unsigned i = 0; playlist_plugins[i] != NULL; ++i) {
		const struct playlist_plugin *plugin = playlist_plugins[i];

		if (playlist_plugins_enabled[i] &&
		    plugin->open_stream != NULL &&
		    plugin->suffixes != NULL &&
		    string_array_contains(plugin->suffixes, suffix)) {
			/* rewind the stream, so each plugin gets a
			   fresh start */
			input_stream_seek(is, 0, SEEK_SET, NULL);

			playlist = playlist_plugin_open_stream(plugin, is);
			if (playlist != NULL)
				return playlist;
		}
	}

	return NULL;
}
Ejemplo n.º 2
0
static bool
decoder_stream_decode(const struct decoder_plugin *plugin,
		      struct decoder *decoder,
		      struct input_stream *input_stream)
{
	assert(plugin != NULL);
	assert(plugin->stream_decode != NULL);
	assert(decoder != NULL);
	assert(decoder->stream_tag == NULL);
	assert(decoder->decoder_tag == NULL);
	assert(input_stream != NULL);
	assert(input_stream->ready);
	assert(decoder->dc->state == DECODE_STATE_START);

	g_debug("probing plugin %s", plugin->name);

	if (decoder->dc->command == DECODE_COMMAND_STOP)
		return true;

	/* rewind the stream, so each plugin gets a fresh start */
	input_stream_seek(input_stream, 0, SEEK_SET, NULL);

	decoder_unlock(decoder->dc);

	decoder_plugin_stream_decode(plugin, decoder, input_stream);

	decoder_lock(decoder->dc);

	assert(decoder->dc->state == DECODE_STATE_START ||
	       decoder->dc->state == DECODE_STATE_DECODE);

	return decoder->dc->state != DECODE_STATE_START;
}
Ejemplo n.º 3
0
/**
 * Skip some bytes from the #input_stream.
 */
static bool
dsdiff_skip(struct decoder *decoder, struct input_stream *is,
	    goffset delta)
{
	assert(delta >= 0);

	if (delta == 0)
		return true;

	if (is->seekable)
		return input_stream_seek(is, delta, SEEK_CUR, NULL);

	char buffer[8192];
	while (delta > 0) {
		size_t length = sizeof(buffer);
		if ((goffset)length > delta)
			length = delta;

		size_t nbytes = decoder_read(decoder, is, buffer, length);
		if (nbytes == 0)
			return false;

		delta -= nbytes;
	}

	return true;
}
Ejemplo n.º 4
0
static void
pcm_stream_decode(struct decoder *decoder, struct input_stream *is)
{
	static const struct audio_format audio_format = {
		.sample_rate = 44100,
		.format = SAMPLE_FORMAT_S16,
		.channels = 2,
	};
	GError *error = NULL;
	enum decoder_command cmd;

	double time_to_size = audio_format_time_to_size(&audio_format);

	float total_time = -1;
	if (is->size >= 0)
		total_time = is->size / time_to_size;

	decoder_initialized(decoder, &audio_format, is->seekable, total_time);

	do {
		char buffer[4096];

		size_t nbytes = decoder_read(decoder, is,
					     buffer, sizeof(buffer));

		if (nbytes == 0 && input_stream_eof(is))
			break;

		cmd = nbytes > 0
			? decoder_data(decoder, is,
				       buffer, nbytes, 0)
			: decoder_get_command(decoder);
		if (cmd == DECODE_COMMAND_SEEK) {
			goffset offset = (goffset)(time_to_size *
						   decoder_seek_where(decoder));
			if (input_stream_seek(is, offset, SEEK_SET, &error)) {
				decoder_command_finished(decoder);
			} else {
				g_warning("seeking failed: %s", error->message);
				g_error_free(error);
				decoder_seek_error(decoder);
			}

			cmd = DECODE_COMMAND_NONE;
		}
	} while (cmd == DECODE_COMMAND_NONE);
}

static const char *const pcm_mime_types[] = {
	/* for streams obtained by the cdio_paranoia input plugin */
	"audio/x-mpd-cdda-pcm",
	NULL
};

const struct decoder_plugin pcm_decoder_plugin = {
	.name = "pcm",
	.stream_decode = pcm_stream_decode,
	.mime_types = pcm_mime_types,
};
Ejemplo n.º 5
0
static bool mp3_seek(struct mp3_data *data, long offset)
{
	if (!input_stream_seek(data->input_stream, offset, SEEK_SET))
		return false;

	mad_stream_buffer(&data->stream, data->input_buffer, 0);
	(data->stream).error = 0;

	return true;
}
Ejemplo n.º 6
0
static long
audiofile_file_seek(AFvirtualfile *vfile, long offset, int is_relative)
{
	struct input_stream *is = (struct input_stream *) vfile->closure;
	int whence = (is_relative ? SEEK_CUR : SEEK_SET);
	if (input_stream_seek(is, offset, whence)) {
		return is->offset;
	} else {
		return -1;
	}
}
static sf_count_t
sndfile_vio_seek(sf_count_t offset, int whence, void *user_data)
{
	struct input_stream *is = user_data;
	bool success;

	success = input_stream_seek(is, offset, whence, NULL);
	if (!success)
		return -1;

	return is->offset;
}
Ejemplo n.º 8
0
/**
 * Skip the #input_stream to the specified offset.
 */
static bool
dsdiff_skip_to(struct decoder *decoder, struct input_stream *is,
	       goffset offset)
{
	if (is->seekable)
		return input_stream_seek(is, offset, SEEK_SET, NULL);

	if (is->offset > offset)
		return false;

	char buffer[8192];
	while (is->offset < offset) {
		size_t length = sizeof(buffer);
		if (offset - is->offset < (goffset)length)
			length = offset - is->offset;

		size_t nbytes = decoder_read(decoder, is, buffer, length);
		if (nbytes == 0)
			return false;
	}

	assert(is->offset == offset);
	return true;
}
Ejemplo n.º 9
0
bool
song_file_update(struct song *song)
{
	const char *suffix;
	char *path_fs;
	const struct decoder_plugin *plugin;
	struct stat st;
	struct input_stream *is = NULL;

	assert(song_is_file(song));

	/* check if there's a suffix and a plugin */

	suffix = uri_get_suffix(song->uri);
	if (suffix == NULL)
		return false;

	plugin = decoder_plugin_from_suffix(suffix, NULL);
	if (plugin == NULL)
		return false;

	path_fs = map_song_fs(song);
	if (path_fs == NULL)
		return false;

	if (song->tag != NULL) {
		tag_free(song->tag);
		song->tag = NULL;
	}

	if (stat(path_fs, &st) < 0 || !S_ISREG(st.st_mode)) {
		g_free(path_fs);
		return false;
	}

	song->mtime = st.st_mtime;

	do {
		/* load file tag */
		song->tag = decoder_plugin_tag_dup(plugin, path_fs);
		if (song->tag != NULL)
			break;

		/* fall back to stream tag */
		if (plugin->stream_tag != NULL) {
			/* open the input_stream (if not already
			   open) */
			if (is == NULL)
				is = input_stream_open(path_fs, NULL);

			/* now try the stream_tag() method */
			if (is != NULL) {
				song->tag = decoder_plugin_stream_tag(plugin,
								      is);
				if (song->tag != NULL)
					break;

				input_stream_seek(is, 0, SEEK_SET, NULL);
			}
		}

		plugin = decoder_plugin_from_suffix(suffix, plugin);
	} while (plugin != NULL);

	if (is != NULL)
		input_stream_close(is);

	if (song->tag != NULL && tag_is_empty(song->tag))
		song->tag = tag_fallback(path_fs, song->tag);

	g_free(path_fs);
	return song->tag != NULL;
}
Ejemplo n.º 10
0
static int
wavpack_input_set_pos_rel(void *id, int32_t delta, int mode)
{
	return input_stream_seek(wpin(id)->is, delta, mode) ? 0 : -1;
}
Ejemplo n.º 11
0
static int
wavpack_input_set_pos_abs(void *id, uint32_t pos)
{
	return input_stream_seek(wpin(id)->is, pos, SEEK_SET) ? 0 : -1;
}