Port all the fixes from BRANCH-GSTREAMER-0_6.

Original commit message from CVS:
Port all the fixes from BRANCH-GSTREAMER-0_6.
This commit is contained in:
Colin Walters 2003-02-07 01:47:58 +00:00
parent bcea95f6cb
commit 44f96d01be

View file

@ -77,8 +77,6 @@ struct _GstGnomeVFSSrc {
/* filename */
gchar *filename;
/* is it a local file ? */
gboolean is_local;
/* uri */
GnomeVFSURI *uri;
@ -87,22 +85,16 @@ struct _GstGnomeVFSSrc {
/* Seek stuff */
gboolean need_flush;
/* local filename */
gchar *local_name;
/* fd for local file fallback */
gint fd;
/* mmap */
guchar *map; /* where the file is mapped to */
/* details for fallback synchronous read */
GnomeVFSFileSize size;
GnomeVFSFileOffset curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
gboolean new_seek;
gboolean in_first_get;
/* icecast/audiocast metadata extraction handling */
gboolean iradio_mode;
gboolean iradio_callbacks_pushed;
gboolean http_callbacks_pushed;
gint icy_metaint;
GnomeVFSFileSize icy_count;
@ -303,19 +295,17 @@ static void gst_gnomevfssrc_init(GstGnomeVFSSrc *gnomevfssrc)
gst_gnomevfssrc_get_formats);
gst_element_add_pad(GST_ELEMENT(gnomevfssrc), gnomevfssrc->srcpad);
gnomevfssrc->filename = NULL;
gnomevfssrc->is_local = FALSE;
gnomevfssrc->uri = NULL;
gnomevfssrc->handle = NULL;
gnomevfssrc->fd = 0;
gnomevfssrc->curoffset = 0;
gnomevfssrc->bytes_per_read = 4096;
gnomevfssrc->new_seek = FALSE;
gnomevfssrc->in_first_get = TRUE;
gnomevfssrc->icy_metaint = 0;
gnomevfssrc->iradio_mode = FALSE;
gnomevfssrc->iradio_callbacks_pushed = FALSE;
gnomevfssrc->http_callbacks_pushed = FALSE;
gnomevfssrc->icy_count = 0;
gnomevfssrc->iradio_name = NULL;
gnomevfssrc->iradio_genre = NULL;
@ -691,12 +681,13 @@ gst_gnomevfssrc_received_headers_callback (gconstpointer in,
GnomeVFSModuleCallbackReceivedHeadersIn *in_args =
(GnomeVFSModuleCallbackReceivedHeadersIn *)in;
/* This is only used for internet radio stuff right now */
if (!src->iradio_mode)
return;
for (i = in_args->headers; i; i = i->next) {
char *data = (char *) i->data;
char *key;
char *key = data;
char *value = strchr(data, ':');
if (!value)
continue;
@ -711,7 +702,8 @@ gst_gnomevfssrc_received_headers_callback (gconstpointer in,
{
sscanf (data + 12, "%d", &icy_metaint);
src->icy_metaint = icy_metaint;
GST_DEBUG (0,"got icy-metaint, killing audiocast thread");
GST_DEBUG (0,"got icy-metaint %d, killing audiocast thread",
src->icy_metaint);
audiocast_thread_kill(src);
continue;
}
@ -746,7 +738,7 @@ gst_gnomevfssrc_received_headers_callback (gconstpointer in,
static void
gst_gnomevfssrc_push_callbacks (GstGnomeVFSSrc *gnomevfssrc)
{
if (gnomevfssrc->iradio_callbacks_pushed)
if (gnomevfssrc->http_callbacks_pushed)
return;
GST_DEBUG (0,"pushing callbacks");
@ -759,13 +751,13 @@ gst_gnomevfssrc_push_callbacks (GstGnomeVFSSrc *gnomevfssrc)
gnomevfssrc,
NULL);
gnomevfssrc->iradio_callbacks_pushed = TRUE;
gnomevfssrc->http_callbacks_pushed = TRUE;
}
static void
gst_gnomevfssrc_pop_callbacks (GstGnomeVFSSrc *gnomevfssrc)
{
if (!gnomevfssrc->iradio_callbacks_pushed)
if (!gnomevfssrc->http_callbacks_pushed)
return;
GST_DEBUG (0,"popping callbacks");
@ -819,7 +811,7 @@ gst_gnomevfssrc_get_icy_metadata (GstGnomeVFSSrc *src)
for (i = 0; tags[i]; i++)
{
if (!g_strncasecmp(tags[i], "StreamTitle=", 12))
if (!g_ascii_strncasecmp(tags[i], "StreamTitle=", 12))
{
if (src->iradio_title)
g_free (src->iradio_title);
@ -827,7 +819,7 @@ gst_gnomevfssrc_get_icy_metadata (GstGnomeVFSSrc *src)
GST_DEBUG(0, "sending notification on icecast title");
g_object_notify (G_OBJECT (src), "iradio-title");
}
if (!g_strncasecmp(tags[i], "StreamUrl=", 10))
if (!g_ascii_strncasecmp(tags[i], "StreamUrl=", 10))
{
if (src->iradio_url)
g_free (src->iradio_url);
@ -874,65 +866,40 @@ static GstBuffer *gst_gnomevfssrc_get(GstPad *pad)
audiocast_do_notifications(src);
/* read it in from the file */
if (src->is_local)
{
/* simply set the buffer to point to the correct region of the
* file */
GST_BUFFER_DATA (buf) = src->map + src->curoffset;
GST_BUFFER_OFFSET (buf) = src->curoffset;
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE);
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_READONLY);
if ((src->curoffset + src->bytes_per_read) > src->size)
{
GST_BUFFER_SIZE (buf) = src->size - src->curoffset;
} else {
GST_BUFFER_SIZE (buf) = src->bytes_per_read;
}
if (src->new_seek)
{
GstEvent *event;
gst_buffer_unref (buf);
GST_DEBUG (0,"new seek %" G_GINT64_FORMAT, src->curoffset);
src->new_seek = FALSE;
GST_DEBUG (GST_CAT_EVENT, "gnomevfssrc sending discont");
event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL);
src->need_flush = FALSE;
return GST_BUFFER (event);
}
src->curoffset += GST_BUFFER_SIZE (buf);
} else if (src->iradio_mode && src->icy_metaint > 0) {
if (src->iradio_mode && src->icy_metaint > 0) {
GST_BUFFER_DATA (buf) = g_malloc0 (src->icy_metaint);
g_return_val_if_fail (GST_BUFFER_DATA (buf) != NULL, NULL);
result = gnome_vfs_read (src->handle, GST_BUFFER_DATA (buf),
src->icy_metaint - src->icy_count,
&readbytes);
/* EOS? */
if (readbytes == 0) {
gst_buffer_unref (buf);
gst_element_set_eos (GST_ELEMENT (src));
return GST_BUFFER (gst_event_new (GST_EVENT_EOS));
}
src->icy_count += readbytes;
GST_BUFFER_OFFSET (buf) = src->curoffset;
GST_BUFFER_SIZE (buf) = readbytes;
src->curoffset += readbytes;
if (src->icy_count == src->icy_metaint) {
gst_gnomevfssrc_get_icy_metadata (src);
src->icy_count = 0;
}
GST_BUFFER_SIZE (buf) = 0;
/* FIXME GROSS HACK: We try to read in at least 8000
* bytes of data so that mp3 typefinding will work. */
do
{
GST_DEBUG (0,"doing read: icy_count: %" G_GINT64_FORMAT, src->icy_count);
result = gnome_vfs_read (src->handle, GST_BUFFER_DATA (buf),
src->icy_metaint - src->icy_count,
&readbytes);
/* EOS? */
if (readbytes == 0) {
gst_buffer_unref (buf);
gst_element_set_eos (GST_ELEMENT (src));
src->in_first_get = FALSE;
return GST_BUFFER (gst_event_new (GST_EVENT_EOS));
}
src->icy_count += readbytes;
GST_BUFFER_OFFSET (buf) = src->curoffset;
GST_BUFFER_SIZE (buf) += readbytes;
src->curoffset += readbytes;
if (src->icy_count == src->icy_metaint) {
gst_gnomevfssrc_get_icy_metadata (src);
src->icy_count = 0;
}
} while (src->in_first_get
&& GST_BUFFER_OFFSET (buf) < 8000 &&
src->icy_metaint - src->icy_count >= 8000);
} else {
/* allocate the space for the buffer data */
GST_BUFFER_DATA(buf) = g_malloc(src->bytes_per_read);
@ -974,15 +941,16 @@ static GstBuffer *gst_gnomevfssrc_get(GstPad *pad)
}
GST_BUFFER_TIMESTAMP (buf) = -1;
src->in_first_get = FALSE;
/* we're done, return the buffer */
return buf;
}
/* open the file and mmap it, necessary to go to READY state */
/* open the file, do stuff necessary to go to READY state */
static gboolean gst_gnomevfssrc_open_file(GstGnomeVFSSrc *src)
{
GnomeVFSResult result;
GnomeVFSFileInfo *info;
g_return_val_if_fail(!GST_FLAG_IS_SET(src, GST_GNOMEVFSSRC_OPEN),
FALSE);
@ -990,98 +958,62 @@ static gboolean gst_gnomevfssrc_open_file(GstGnomeVFSSrc *src)
/* create the uri */
src->uri = gnome_vfs_uri_new(src->filename);
if (!src->uri) {
gst_element_error(GST_ELEMENT(src),
"creating uri \"%s\" (%s)",
src->filename, strerror (errno));
gst_element_error(GST_ELEMENT(src), "creating uri \"%s\" (%s)",
src->filename, strerror (errno));
return FALSE;
}
/* open the file using open() if the file is local */
src->is_local = gnome_vfs_uri_is_local(src->uri);
if (src->is_local) {
src->local_name =
gnome_vfs_get_local_path_from_uri(src->filename);
src->fd = open(src->local_name, O_RDONLY);
if (src->fd < 0)
{
gst_element_error(GST_ELEMENT(src),
"opening local file \"%s\" (%s)",
src->filename, strerror (errno));
return FALSE;
}
/* find the file length */
src->size = lseek (src->fd, 0, SEEK_END);
lseek (src->fd, 0, SEEK_SET);
src->map = mmap (NULL, src->size, PROT_READ, MAP_SHARED,
src->fd, 0);
madvise (src->map,src->size, 2);
/* collapse state if that failed */
if (src->map == NULL)
{
gst_gnomevfssrc_close_file(src);
gst_element_error (GST_ELEMENT (src),"mmapping file");
return FALSE;
}
src->new_seek = TRUE;
} else {
if (!audiocast_init(src))
return FALSE;
if (!audiocast_init(src))
return FALSE;
gst_gnomevfssrc_push_callbacks (src);
result =
gnome_vfs_open_uri(&(src->handle), src->uri,
GNOME_VFS_OPEN_READ);
if (result != GNOME_VFS_OK)
{
gst_gnomevfssrc_pop_callbacks (src);
audiocast_thread_kill(src);
gst_element_error(GST_ELEMENT(src),
gst_gnomevfssrc_push_callbacks (src);
result = gnome_vfs_open_uri(&(src->handle), src->uri,
GNOME_VFS_OPEN_READ);
if (result != GNOME_VFS_OK)
{
gst_gnomevfssrc_pop_callbacks (src);
audiocast_thread_kill(src);
gst_element_error(GST_ELEMENT(src),
"opening vfs file \"%s\" (%s)",
src->filename,
gnome_vfs_result_to_string(result));
return FALSE;
}
/* find the file length (but skip it in iradio mode,
* since it will require a separate request, and we
* know the length is undefined anyways) */
if (!src->iradio_mode)
src->filename,
gnome_vfs_result_to_string(result));
return FALSE;
}
info = gnome_vfs_file_info_new ();
if (gnome_vfs_get_file_info_from_handle (src->handle, info,
GNOME_VFS_FILE_INFO_DEFAULT | GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
== GNOME_VFS_OK)
{
if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
src->size = info->size;
if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE)
{
GnomeVFSResult size_result;
GnomeVFSFileInfo *info;
info = gnome_vfs_file_info_new ();
size_result = gnome_vfs_get_file_info_uri(src->uri,
info, GNOME_VFS_FILE_INFO_DEFAULT);
if (size_result != GNOME_VFS_OK)
src->size = 0;
else
src->size = info->size;
gnome_vfs_file_info_unref(info);
GST_DEBUG (0, "got MIME type \"%s\", setting caps",
info->mime_type);
GstCaps *caps = gst_caps_new ("gnomevfssrc", info->mime_type, NULL);
gst_pad_try_set_caps (src->srcpad, caps);
}
else
src->size = 0;
GST_DEBUG(0, "size %" G_GINT64_FORMAT, src->size);
audiocast_do_notifications(src);
GST_DEBUG(0, "open %s", gnome_vfs_result_to_string(result));
GST_DEBUG (0, "No mime type available");
}
else
GST_DEBUG (0, "getting info failed: %s", gnome_vfs_result_to_string (result));
gnome_vfs_file_info_unref(info);
GST_DEBUG(0, "size %" G_GINT64_FORMAT, src->size);
audiocast_do_notifications(src);
GST_DEBUG(0, "open result: %s", gnome_vfs_result_to_string (result));
GST_FLAG_SET(src, GST_GNOMEVFSSRC_OPEN);
return TRUE;
}
/* unmap and close the file */
static void gst_gnomevfssrc_close_file(GstGnomeVFSSrc *src)
{
g_return_if_fail(GST_FLAG_IS_SET(src, GST_GNOMEVFSSRC_OPEN));
@ -1089,22 +1021,9 @@ static void gst_gnomevfssrc_close_file(GstGnomeVFSSrc *src)
gst_gnomevfssrc_pop_callbacks (src);
audiocast_thread_kill(src);
/* close the file */
if (src->is_local)
{
/* unmap the file from memory */
munmap (src->map, src->size);
close(src->fd);
} else {
gnome_vfs_close(src->handle);
}
gnome_vfs_close(src->handle);
/* zero out a lot of our state */
src->is_local = FALSE;
gnome_vfs_uri_unref(src->uri);
g_free(src->local_name);
src->fd = 0;
src->map = NULL;
src->size = 0;
src->curoffset = 0;
src->new_seek = FALSE;
@ -1214,18 +1133,16 @@ gst_gnomevfssrc_srcpad_event (GstPad *pad, GstEvent *event)
return FALSE;
break;
}
if (!src->is_local) {
GnomeVFSResult result;
result = gnome_vfs_seek(src->handle,
GnomeVFSResult result;
result = gnome_vfs_seek(src->handle,
GNOME_VFS_SEEK_START, desired_offset);
GST_DEBUG(0, "new_seek: %s",
gnome_vfs_result_to_string(result));
if (result != GNOME_VFS_OK) {
gst_event_unref (event);
return FALSE;
}
GST_DEBUG(0, "new_seek: %s",
gnome_vfs_result_to_string(result));
if (result != GNOME_VFS_OK) {
gst_event_unref (event);
return FALSE;
}
src->curoffset = desired_offset;
src->new_seek = TRUE;