Пример #1
0
static uint32_t
wavpack_get_pos (void *id)
{
	xmms_xform_t *xform = id;
	xmms_wavpack_data_t *data;
	xmms_error_t error;

	g_return_val_if_fail (xform, (uint32_t)-1);

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, (uint32_t)-1);

	gint64 pos = xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_CUR, &error);

	if (data->pushback_set) {
		/* we didn't actually perform the pushback on the
		   underlying stream so adjust offset accordingly */
		pos--;
	}

	return (uint32_t)pos;
}
Пример #2
0
static gint64
xmms_mad_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
{
	xmms_mad_data_t *data;
	guint bytes;
	gint64 res;

	g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1);
	g_return_val_if_fail (xform, -1);

	data = xmms_xform_private_data_get (xform);

	if (data->xing &&
	    xmms_xing_has_flag (data->xing, XMMS_XING_FRAMES) &&
	    xmms_xing_has_flag (data->xing, XMMS_XING_TOC)) {
		guint i;

		i = (guint) (100ULL * samples / xmms_xing_get_frames (data->xing) / 1152);

		bytes = xmms_xing_get_toc (data->xing, i) * (xmms_xing_get_bytes (data->xing) / 256);
	} else {
		bytes = (guint)(((gdouble)samples) * data->bitrate / data->samplerate) / 8;
	}

	XMMS_DBG ("Try seek %" G_GINT64_FORMAT " samples -> %d bytes", samples, bytes);

	res = xmms_xform_seek (xform, bytes, XMMS_XFORM_SEEK_SET, err);
	if (res == -1) {
		return -1;
	}

	/* we don't have sample accuracy when seeking,
	   so there is no use trying */
	data->samples_to_skip = 0;
	data->samples_to_play = -1;

	return samples;
}
Пример #3
0
static uint32_t
xmms_mp4_seek_callback (void *user_data, uint64_t position)
{
	xmms_xform_t *xform;
	xmms_mp4_data_t *data;
	xmms_error_t error;
	gint ret = 0;

	g_return_val_if_fail (user_data, -1);
	xform = user_data;

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, -1);

	ret = xmms_xform_seek (xform, position, XMMS_XFORM_SEEK_SET, &error);

	/* If seeking was successfull, flush the internal buffer */
	if (ret >= 0) {
		data->buffer_length = 0;
	}

	return ret;
}
Пример #4
0
static int
opus_callback_seek (void *datasource, opus_int64 offset, int whence)
{
	xmms_xform_t *xform = datasource;
	xmms_error_t err;
	gint ret;

	g_return_val_if_fail (xform, -1);

	xmms_error_reset (&err);

	if (whence == SEEK_CUR) {
		whence = XMMS_XFORM_SEEK_CUR;
	} else if (whence == SEEK_SET) {
		whence = XMMS_XFORM_SEEK_SET;
	} else if (whence == SEEK_END) {
		whence = XMMS_XFORM_SEEK_END;
	}

	ret = xmms_xform_seek (xform, (gint64) offset, whence, &err);

	return (ret == -1) ? -1 : 0;
}
Пример #5
0
/* return 0 on success, -1 on error */
static int
wavpack_set_pos_abs (void *id, uint32_t pos)
{
	xmms_xform_t *xform = id;
	xmms_wavpack_data_t *data;
	xmms_error_t error;
	gint ret;

	g_return_val_if_fail (xform, -1);

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, -1);

	ret = xmms_xform_seek (xform, pos, XMMS_XFORM_SEEK_SET, &error);

	if (ret == -1) {
		return -1;
	}

	data->pushback_set = FALSE;

	return 0;
}
Пример #6
0
static gboolean
xmms_mp4_init (xmms_xform_t *xform)
{
	xmms_mp4_data_t *data;
	xmms_error_t error;

	gint bytes_read;

	guchar *tmpbuf;
	guint tmpbuflen;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_mp4_data_t, 1);
	data->outbuf = g_string_new (NULL);
	data->buffer_size = MP4_BUFFER_SIZE;

	xmms_xform_private_data_set (xform, data);

	data->sampleid = 1;
	data->numsamples = 0;

	bytes_read = xmms_xform_read (xform,
	                              (gchar *) data->buffer + data->buffer_length,
	                              data->buffer_size - data->buffer_length,
	                              &error);

	data->buffer_length += bytes_read;

	if (bytes_read < 8) {
		XMMS_DBG ("Not enough bytes to check the MP4 header");
		goto err;
	}

	/*
	 * MP4 not supported (yet) on non-seekable transport
	 * this needs little tweaking in mp4ff at least
	 */
	if (xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_CUR, &error) < 0) {
		XMMS_DBG ("Non-seekable transport on MP4 not yet supported");
		goto err;
	}

	data->mp4ff_cb = g_new0 (mp4ff_callback_t, 1);
	data->mp4ff_cb->read = xmms_mp4_read_callback;
	data->mp4ff_cb->seek = xmms_mp4_seek_callback;
	data->mp4ff_cb->user_data = xform;

	data->mp4ff = mp4ff_open_read (data->mp4ff_cb);
	if (!data->mp4ff) {
		XMMS_DBG ("Error opening mp4 demuxer\n");
		goto err;;
	}

	data->track = xmms_mp4_get_track (xform, data->mp4ff);
	if (data->track < 0) {
		XMMS_DBG ("Can't find suitable audio track from MP4 file\n");
		goto err;
	}
	data->numsamples = mp4ff_num_samples (data->mp4ff, data->track);

	mp4ff_get_decoder_config (data->mp4ff, data->track, &tmpbuf,
	                          &tmpbuflen);
	xmms_xform_auxdata_set_bin (xform, "decoder_config", tmpbuf, tmpbuflen);
	g_free (tmpbuf);

	xmms_mp4_get_mediainfo (xform);

	XMMS_DBG ("MP4 demuxer inited successfully!");

	return TRUE;

err:
	g_free (data->mp4ff_cb);
	g_string_free (data->outbuf, TRUE);
	g_free (data);

	return FALSE;
}
Пример #7
0
static gint64
xmms_vocoder_seek (xmms_xform_t *xform, gint64 offset,
                   xmms_xform_seek_mode_t whence, xmms_error_t *err)
{
	return xmms_xform_seek (xform, offset, whence, err);
}
Пример #8
0
static gboolean
xmms_apetag_read (xmms_xform_t *xform)
{
	guchar buffer[32], *tagdata;
	xmms_error_t error;
	guint version, tag_size, items, flags;
	gint64 tag_position;
	gint pos, i, ret;

	g_return_val_if_fail (xform, FALSE);

	/* Try to find the 32-byte footer from the end of file */
	tag_position = xmms_xform_seek (xform, -32, XMMS_XFORM_SEEK_END, &error);
	if (tag_position < 0) {
		/* Seeking failed, failed to read tags */
		return FALSE;
	}

	/* Read footer data if seeking was possible */
	ret = xmms_xform_read (xform, buffer, 32, &error);
	if (ret != 32) {
		xmms_log_error ("Failed to read APE tag footer");
		return FALSE;
	}

	/* Check that the footer is valid, if not continue searching */
	if (memcmp (buffer, "APETAGEX", 8)) {
		/* Try to find the 32-byte footer before 128-byte ID3v1 tag */
		tag_position = xmms_xform_seek (xform, -160, XMMS_XFORM_SEEK_END, &error);
		if (tag_position < 0) {
			/* Seeking failed, failed to read tags */
			xmms_log_error ("Failed to seek to APE tag footer");
			return FALSE;
		}

		/* Read footer data if seeking was possible */
		ret = xmms_xform_read (xform, buffer, 32, &error);
		if (ret != 32) {
			xmms_log_error ("Failed to read APE tag footer");
			return FALSE;
		}

		if (memcmp (buffer, "APETAGEX", 8)) {
			/* Didn't find any APE tag from the file */
			return FALSE;
		}
	}

	version = xmms_apetag_get_le32 (buffer + 8);
	tag_size = xmms_apetag_get_le32 (buffer + 12);
	items = xmms_apetag_get_le32 (buffer + 16);
	flags = xmms_apetag_get_le32 (buffer + 20);

	if (flags & APE_TAG_FLAG_IS_HEADER) {
		/* We need a footer, not a header... */
		return FALSE;
	}

	if (version != 1000 && version != 2000) {
		xmms_log_error ("Invalid tag version, the writer is probably corrupted!");
		return FALSE;
	}

	/* Seek to the beginning of the actual tag data */
	ret = xmms_xform_seek (xform, tag_position - tag_size + 32,
	                       XMMS_XFORM_SEEK_SET, &error);
	if (ret < 0) {
		xmms_log_error ("Couldn't seek to the tag starting position, returned %d", ret);
		return FALSE;
	}

	tagdata = g_malloc (tag_size);
	ret = xmms_xform_read (xform, tagdata, tag_size, &error);
	if (ret != tag_size) {
		xmms_log_error ("Couldn't read the tag data, returned %d", ret);
		g_free (tagdata);
		return FALSE;
	}

	pos = 0;
	for (i = 0; i < items; i++) {
		gint itemlen, flags;
		gchar *key, *item;

		itemlen = xmms_apetag_get_le32 (tagdata + pos);
		pos += 4;
		flags = xmms_apetag_get_le32 (tagdata + pos);
		pos += 4;
		key = (gchar *) tagdata + pos;
		pos += strlen (key) + 1;

		switch (flags & APE_TAG_FLAG_DATA_TYPE) {
			case APE_TAG_DATA_TYPE_UTF8:
				item = g_strndup ((gchar *) tagdata + pos, itemlen);
				break;
			case APE_TAG_DATA_TYPE_BINARY:
				item = g_malloc (itemlen);
				memcpy (item, tagdata + pos, itemlen);
				break;
			case APE_TAG_DATA_TYPE_LOCATOR:
				item = NULL;
				break;
		}

		if (item != NULL && !xmms_xform_metadata_mapper_match (xform, key, item, itemlen)) {
			if ((flags & APE_TAG_FLAG_DATA_TYPE) == APE_TAG_DATA_TYPE_UTF8) {
				XMMS_DBG ("Unhandled tag '%s' = '%s'", key, item);
			} else {
				XMMS_DBG ("Unhandled tag '%s' = '(binary)'", key);
			}
		}

		g_free (item);
		pos += itemlen;
	}
	g_free (tagdata);

	return TRUE;
}
Пример #9
0
static gint64
xmms_xml_seek (xmms_xform_t *xform, gint64 samples,
               xmms_xform_seek_mode_t whence, xmms_error_t *err)
{
	return xmms_xform_seek (xform, samples, whence, err);
}