diff --git a/gst/cothreads.c b/gst/cothreads.c index 44feacf447..8d0260a3d6 100644 --- a/gst/cothreads.c +++ b/gst/cothreads.c @@ -94,6 +94,7 @@ cothread_init (void) // we consider the initiating process to be cothread 0 ctx->nthreads = 1; ctx->current = 0; + ctx->data = g_hash_table_new(g_str_hash, g_str_equal); return ctx; } @@ -122,6 +123,25 @@ cothread_stub (void) //printf("uh, yeah, we shouldn't be here, but we should deal anyway\n"); } +void +cothread_set_data (cothread_state *thread, + gchar *key, + gpointer data) +{ + cothread_context *ctx = pthread_getspecific(_cothread_key); + + g_hash_table_insert(ctx->data, key, data); +} + +gpointer +cothread_get_data (cothread_state *thread, + gchar *key) +{ + cothread_context *ctx = pthread_getspecific(_cothread_key); + + return g_hash_table_lookup(ctx->data, key); +} + void cothread_switch (cothread_state *thread) { diff --git a/gst/cothreads.h b/gst/cothreads.h index 57ba54625f..e09cbba5b5 100644 --- a/gst/cothreads.h +++ b/gst/cothreads.h @@ -38,6 +38,7 @@ struct _cothread_context { cothread_state *threads[COTHREAD_MAXTHREADS]; int nthreads; int current; + GHashTable *data; }; cothread_context* cothread_init(); @@ -45,6 +46,9 @@ cothread_state* cothread_create (cothread_context *ctx); void cothread_setfunc (cothread_state *thread, cothread_func func, int argc, char **argv); void cothread_switch (cothread_state *thread); +void cothread_set_data (cothread_state *thread, gchar *key, gpointer data); +gpointer cothread_get_data (cothread_state *thread, gchar *key); + cothread_state* cothread_main (cothread_context *ctx); #endif /* __COTHREAD_H__ */ diff --git a/gst/elements/Makefile.am b/gst/elements/Makefile.am index 5c6a39c37b..bf57b271ca 100644 --- a/gst/elements/Makefile.am +++ b/gst/elements/Makefile.am @@ -42,7 +42,7 @@ noinst_HEADERS = \ gsttypefind.h \ gstsinesrc.h -CFLAGS += -g -O2 -Wall +CFLAGS += -O2 -Wall libgstelements_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(GHTTP_LIBS) libgstelements_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE) diff --git a/gst/elements/gstasyncdisksrc.c b/gst/elements/gstasyncdisksrc.c index 3bb7fab4ba..57cc0dc0f3 100644 --- a/gst/elements/gstasyncdisksrc.c +++ b/gst/elements/gstasyncdisksrc.c @@ -51,22 +51,24 @@ enum { }; -static void gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass); -static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc); -static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id); -static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_asyncdisksrc_class_init (GstAsyncDiskSrcClass *klass); +static void gst_asyncdisksrc_init (GstAsyncDiskSrc *asyncdisksrc); -static void gst_asyncdisksrc_push(GstSrc *src); -static void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset, - gulong size); -static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element); +static void gst_asyncdisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_asyncdisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); + +static void gst_asyncdisksrc_push (GstSrc *src); +static void gst_asyncdisksrc_push_region (GstSrc *src, gulong offset, gulong size); + +static GstElementStateReturn gst_asyncdisksrc_change_state (GstElement *element); static GstSrcClass *parent_class = NULL; //static guint gst_asyncdisksrc_signals[LAST_SIGNAL] = { 0 }; GtkType -gst_asyncdisksrc_get_type(void) { +gst_asyncdisksrc_get_type(void) +{ static GtkType asyncdisksrc_type = 0; if (!asyncdisksrc_type) { @@ -80,13 +82,14 @@ gst_asyncdisksrc_get_type(void) { (GtkArgGetFunc)gst_asyncdisksrc_get_arg, (GtkClassInitFunc)NULL, }; - asyncdisksrc_type = gtk_type_unique(GST_TYPE_SRC,&asyncdisksrc_info); + asyncdisksrc_type = gtk_type_unique (GST_TYPE_SRC, &asyncdisksrc_info); } return asyncdisksrc_type; } static void -gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass) { +gst_asyncdisksrc_class_init (GstAsyncDiskSrcClass *klass) +{ GtkObjectClass *gtkobject_class; GstElementClass *gstelement_class; GstSrcClass *gstsrc_class; @@ -95,31 +98,33 @@ gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass) { gstelement_class = (GstElementClass*)klass; gstsrc_class = (GstSrcClass*)klass; - parent_class = gtk_type_class(GST_TYPE_SRC); + parent_class = gtk_type_class (GST_TYPE_SRC); - gtk_object_add_arg_type("GstAsyncDiskSrc::location", GST_TYPE_FILENAME, - GTK_ARG_READWRITE, ARG_LOCATION); - gtk_object_add_arg_type("GstAsyncDiskSrc::bytesperread", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_BYTESPERREAD); - gtk_object_add_arg_type("GstAsyncDiskSrc::offset", GTK_TYPE_LONG, - GTK_ARG_READWRITE, ARG_OFFSET); - gtk_object_add_arg_type("GstAsyncDiskSrc::size", GTK_TYPE_LONG, - GTK_ARG_READABLE, ARG_SIZE); + gtk_object_add_arg_type ("GstAsyncDiskSrc::location", GST_TYPE_FILENAME, + GTK_ARG_READWRITE, ARG_LOCATION); + gtk_object_add_arg_type ("GstAsyncDiskSrc::bytesperread", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_BYTESPERREAD); + gtk_object_add_arg_type ("GstAsyncDiskSrc::offset", GTK_TYPE_LONG, + GTK_ARG_READWRITE, ARG_OFFSET); + gtk_object_add_arg_type ("GstAsyncDiskSrc::size", GTK_TYPE_LONG, + GTK_ARG_READABLE, ARG_SIZE); gtkobject_class->set_arg = gst_asyncdisksrc_set_arg; gtkobject_class->get_arg = gst_asyncdisksrc_get_arg; gstelement_class->change_state = gst_asyncdisksrc_change_state; - gstsrc_class->push = gst_asyncdisksrc_push; - gstsrc_class->push_region = gst_asyncdisksrc_push_region; + gstsrc_class->push = gst_asyncdisksrc_push; + gstsrc_class->push_region = gst_asyncdisksrc_push_region; } -static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc) { - GST_SRC_SET_FLAGS(asyncdisksrc,GST_SRC_ASYNC); +static void +gst_asyncdisksrc_init (GstAsyncDiskSrc *asyncdisksrc) +{ + GST_SRC_SET_FLAGS (asyncdisksrc, GST_SRC_ASYNC); - asyncdisksrc->srcpad = gst_pad_new("src",GST_PAD_SRC); - gst_element_add_pad(GST_ELEMENT(asyncdisksrc),asyncdisksrc->srcpad); + asyncdisksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_element_add_pad (GST_ELEMENT (asyncdisksrc), asyncdisksrc->srcpad); asyncdisksrc->filename = NULL; asyncdisksrc->fd = 0; @@ -128,61 +133,69 @@ static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc) { asyncdisksrc->curoffset = 0; asyncdisksrc->bytes_per_read = 4096; asyncdisksrc->seq = 0; + asyncdisksrc->new_seek = FALSE; } -static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { +static void +gst_asyncdisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +{ GstAsyncDiskSrc *src; /* it's not null if we got it, but it might not be ours */ - g_return_if_fail(GST_IS_ASYNCDISKSRC(object)); - src = GST_ASYNCDISKSRC(object); + g_return_if_fail (GST_IS_ASYNCDISKSRC (object)); + + src = GST_ASYNCDISKSRC (object); switch(id) { case ARG_LOCATION: /* the element must be stopped in order to do this */ - g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); + g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING); - if (src->filename) g_free(src->filename); + if (src->filename) g_free (src->filename); /* clear the filename if we get a NULL (is that possible?) */ - if (GTK_VALUE_STRING(*arg) == NULL) { - gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); + if (GTK_VALUE_STRING (*arg) == NULL) { + gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); src->filename = NULL; /* otherwise set the new filename */ } else { - src->filename = g_strdup(GTK_VALUE_STRING(*arg)); + src->filename = g_strdup (GTK_VALUE_STRING (*arg)); } break; case ARG_BYTESPERREAD: - src->bytes_per_read = GTK_VALUE_INT(*arg); + src->bytes_per_read = GTK_VALUE_INT (*arg); break; case ARG_OFFSET: - src->curoffset = GTK_VALUE_LONG(*arg); + src->curoffset = GTK_VALUE_LONG (*arg); + src->new_seek = TRUE; break; default: break; } } -static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { +static void +gst_asyncdisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +{ GstAsyncDiskSrc *src; /* it's not null if we got it, but it might not be ours */ - g_return_if_fail(GST_IS_ASYNCDISKSRC(object)); - src = GST_ASYNCDISKSRC(object); + g_return_if_fail (GST_IS_ASYNCDISKSRC (object)); + + src = GST_ASYNCDISKSRC (object); switch (id) { case ARG_LOCATION: - GTK_VALUE_STRING(*arg) = src->filename; + GTK_VALUE_STRING (*arg) = src->filename; break; case ARG_BYTESPERREAD: - GTK_VALUE_INT(*arg) = src->bytes_per_read; + GTK_VALUE_INT (*arg) = src->bytes_per_read; break; case ARG_OFFSET: - GTK_VALUE_LONG(*arg) = src->curoffset; + GTK_VALUE_LONG (*arg) = src->curoffset; break; case ARG_SIZE: - GTK_VALUE_LONG(*arg) = src->size; + GTK_VALUE_LONG (*arg) = src->size; break; default: arg->type = GTK_TYPE_INVALID; @@ -196,43 +209,51 @@ static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { * * Push a new buffer from the asyncdisksrc at the current offset. */ -void gst_asyncdisksrc_push(GstSrc *src) { +static void +gst_asyncdisksrc_push (GstSrc *src) +{ GstAsyncDiskSrc *asyncdisksrc; GstBuffer *buf; - g_return_if_fail(src != NULL); - g_return_if_fail(GST_IS_ASYNCDISKSRC(src)); - g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN)); - asyncdisksrc = GST_ASYNCDISKSRC(src); + g_return_if_fail (src != NULL); + g_return_if_fail (GST_IS_ASYNCDISKSRC (src)); + g_return_if_fail (GST_FLAG_IS_SET (src, GST_ASYNCDISKSRC_OPEN)); + + asyncdisksrc = GST_ASYNCDISKSRC (src); /* deal with EOF state */ if (asyncdisksrc->curoffset >= asyncdisksrc->size) { - gst_src_signal_eos(GST_SRC(asyncdisksrc)); + gst_src_signal_eos (GST_SRC (asyncdisksrc)); return; } /* create the buffer */ // FIXME: should eventually use a bufferpool for this - buf = gst_buffer_new(); - g_return_if_fail(buf != NULL); + buf = gst_buffer_new (); + + g_return_if_fail (buf != NULL); /* simply set the buffer to point to the correct region of the file */ - GST_BUFFER_DATA(buf) = asyncdisksrc->map + asyncdisksrc->curoffset; - GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset; - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_DONTFREE); + GST_BUFFER_DATA (buf) = asyncdisksrc->map + asyncdisksrc->curoffset; + GST_BUFFER_OFFSET (buf) = asyncdisksrc->curoffset; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if ((asyncdisksrc->curoffset + asyncdisksrc->bytes_per_read) > asyncdisksrc->size) { - GST_BUFFER_SIZE(buf) = asyncdisksrc->size - asyncdisksrc->curoffset; + GST_BUFFER_SIZE (buf) = asyncdisksrc->size - asyncdisksrc->curoffset; // FIXME: set the buffer's EOF bit here } else - GST_BUFFER_SIZE(buf) = asyncdisksrc->bytes_per_read; - asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf); + GST_BUFFER_SIZE (buf) = asyncdisksrc->bytes_per_read; - //gst_buffer_ref(buf); + asyncdisksrc->curoffset += GST_BUFFER_SIZE (buf); + + if (asyncdisksrc->new_seek) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH); + asyncdisksrc->new_seek = FALSE; + } /* we're done, push the buffer off now */ - gst_pad_push(asyncdisksrc->srcpad,buf); + gst_pad_push (asyncdisksrc->srcpad, buf); } /** @@ -243,78 +264,84 @@ void gst_asyncdisksrc_push(GstSrc *src) { * * Push a new buffer from the asyncdisksrc of given size at given offset. */ -void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) { +static void +gst_asyncdisksrc_push_region (GstSrc *src, gulong offset, gulong size) +{ GstAsyncDiskSrc *asyncdisksrc; GstBuffer *buf; - g_return_if_fail(src != NULL); - g_return_if_fail(GST_IS_ASYNCDISKSRC(src)); - g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_READY)); - asyncdisksrc = GST_ASYNCDISKSRC(src); + g_return_if_fail (src != NULL); + g_return_if_fail (GST_IS_ASYNCDISKSRC (src)); + g_return_if_fail (GST_FLAG_IS_SET (src, GST_ASYNCDISKSRC_OPEN)); + + asyncdisksrc = GST_ASYNCDISKSRC (src); /* deal with EOF state */ if (offset >= asyncdisksrc->size) { - gst_src_signal_eos(GST_SRC(asyncdisksrc)); + gst_src_signal_eos (GST_SRC (asyncdisksrc)); return; } /* create the buffer */ // FIXME: should eventually use a bufferpool for this - buf = gst_buffer_new(); - g_return_if_fail(buf); + buf = gst_buffer_new (); + g_return_if_fail (buf); /* simply set the buffer to point to the correct region of the file */ - GST_BUFFER_DATA(buf) = asyncdisksrc->map + offset; - GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset; - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_DONTFREE); + GST_BUFFER_DATA (buf) = asyncdisksrc->map + offset; + GST_BUFFER_OFFSET (buf) = offset; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if ((offset + size) > asyncdisksrc->size) { - GST_BUFFER_SIZE(buf) = asyncdisksrc->size - offset; + GST_BUFFER_SIZE (buf) = asyncdisksrc->size - offset; // FIXME: set the buffer's EOF bit here } else - GST_BUFFER_SIZE(buf) = size; - asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf); + GST_BUFFER_SIZE (buf) = size; /* we're done, push the buffer off now */ - gst_pad_push(asyncdisksrc->srcpad,buf); + gst_pad_push (asyncdisksrc->srcpad,buf); } /* open the file and mmap it, necessary to go to READY state */ -static gboolean gst_asyncdisksrc_open_file(GstAsyncDiskSrc *src) { - g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN), FALSE); +static +gboolean gst_asyncdisksrc_open_file (GstAsyncDiskSrc *src) +{ + g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_ASYNCDISKSRC_OPEN), FALSE); /* open the file */ - src->fd = open(src->filename,O_RDONLY); + src->fd = open (src->filename, O_RDONLY); if (src->fd < 0) { - gst_element_error(GST_ELEMENT(src),"opening file"); + gst_element_error (GST_ELEMENT (src), "opening file"); return FALSE; } else { /* find the file length */ - src->size = lseek(src->fd,0,SEEK_END); - lseek(src->fd,0,SEEK_SET); + src->size = lseek (src->fd, 0, SEEK_END); + lseek (src->fd, 0, SEEK_SET); /* map the file into memory */ - src->map = mmap(NULL,src->size,PROT_READ,MAP_SHARED,src->fd,0); - madvise(src->map,src->size,2); + 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) { - close(src->fd); - gst_element_error(GST_ELEMENT(src),"mmapping file"); + close (src->fd); + gst_element_error (GST_ELEMENT (src),"mmapping file"); return FALSE; } - GST_FLAG_SET(src,GST_ASYNCDISKSRC_OPEN); + GST_FLAG_SET (src, GST_ASYNCDISKSRC_OPEN); } return TRUE; } /* unmap and close the file */ -static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) { - g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN)); +static void +gst_asyncdisksrc_close_file (GstAsyncDiskSrc *src) +{ + g_return_if_fail (GST_FLAG_IS_SET (src, GST_ASYNCDISKSRC_OPEN)); /* unmap the file from memory */ - munmap(src->map,src->size); + munmap (src->map, src->size); /* close the file */ - close(src->fd); + close (src->fd); /* zero out a lot of our state */ src->fd = 0; @@ -323,25 +350,27 @@ static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) { src->curoffset = 0; src->seq = 0; - GST_FLAG_UNSET(src,GST_ASYNCDISKSRC_OPEN); + GST_FLAG_UNSET (src, GST_ASYNCDISKSRC_OPEN); } -static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element) { - g_return_val_if_fail(GST_IS_ASYNCDISKSRC(element),GST_STATE_FAILURE); +static +GstElementStateReturn gst_asyncdisksrc_change_state (GstElement *element) +{ + g_return_val_if_fail (GST_IS_ASYNCDISKSRC (element), GST_STATE_FAILURE); - if (GST_STATE_PENDING(element) == GST_STATE_NULL) { - if (GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) - gst_asyncdisksrc_close_file(GST_ASYNCDISKSRC(element)); + if (GST_STATE_PENDING (element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET (element, GST_ASYNCDISKSRC_OPEN)) + gst_asyncdisksrc_close_file (GST_ASYNCDISKSRC (element)); } else { - if (!GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) { - if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element))) + if (!GST_FLAG_IS_SET (element, GST_ASYNCDISKSRC_OPEN)) { + if (!gst_asyncdisksrc_open_file (GST_ASYNCDISKSRC (element))) return GST_STATE_FAILURE; } } - if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element); + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); return GST_STATE_SUCCESS; } diff --git a/gst/elements/gstasyncdisksrc.h b/gst/elements/gstasyncdisksrc.h index 6add9425b9..60a9976f1a 100644 --- a/gst/elements/gstasyncdisksrc.h +++ b/gst/elements/gstasyncdisksrc.h @@ -70,6 +70,7 @@ struct _GstAsyncDiskSrc { /* details for fallback synchronous read */ gulong curoffset; /* current offset in file */ gulong bytes_per_read; /* bytes per read */ + gboolean new_seek; gulong seq; /* buffer sequence number */ }; diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c index fc50da5acf..51efc3786d 100644 --- a/gst/elements/gstdisksrc.c +++ b/gst/elements/gstdisksrc.c @@ -52,16 +52,17 @@ enum { }; -static void gst_disksrc_class_init(GstDiskSrcClass *klass); -static void gst_disksrc_init(GstDiskSrc *disksrc); -static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id); -static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_disksrc_class_init (GstDiskSrcClass *klass); +static void gst_disksrc_init (GstDiskSrc *disksrc); -static void gst_disksrc_close_file(GstDiskSrc *src); +static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_disksrc_push(GstSrc *src); -//static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size); -static GstElementStateReturn gst_disksrc_change_state(GstElement *element); +static void gst_disksrc_close_file (GstDiskSrc *src); + +static void gst_disksrc_push (GstSrc *src); + +static GstElementStateReturn gst_disksrc_change_state (GstElement *element); static GstSrcClass *parent_class = NULL; @@ -104,7 +105,7 @@ gst_disksrc_class_init(GstDiskSrcClass *klass) { gtk_object_add_arg_type("GstDiskSrc::bytesperread", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_BYTESPERREAD); gtk_object_add_arg_type("GstDiskSrc::offset", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_OFFSET); + GTK_ARG_READABLE, ARG_OFFSET); gtk_object_add_arg_type("GstDiskSrc::size", GTK_TYPE_INT, GTK_ARG_READABLE, ARG_SIZE); @@ -157,11 +158,13 @@ static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { case ARG_BYTESPERREAD: src->bytes_per_read = GTK_VALUE_INT(*arg); break; + /* case ARG_OFFSET: src->curoffset = GTK_VALUE_INT(*arg); lseek(src->fd,src->curoffset, SEEK_SET); src->new_seek = TRUE; break; + */ default: break; } diff --git a/gst/gstbin.c b/gst/gstbin.c index f691a3f411..41c7d5b50b 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -504,6 +504,11 @@ gst_bin_create_plan (GstBin *bin) (oclass->create_plan) (bin); } +typedef struct { + gulong offset; + gulong size; +} region_struct; + static int gst_bin_loopfunc_wrapper (int argc,char *argv[]) { @@ -525,9 +530,15 @@ gst_bin_loopfunc_wrapper (int argc,char *argv[]) } else { DEBUG("** gst_bin_loopfunc_wrapper(): element %s is chain-based, calling in infinite loop\n", name); if (GST_IS_SRC (element)) { - DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source %s\n", name); - gst_src_push (GST_SRC (element)); - DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source %s done\n", name); + region_struct *region = cothread_get_data (element->threadstate, "region"); + if (region) { + gst_src_push_region (GST_SRC (element), region->offset, region->size); + } + else { + DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source %s\n", name); + gst_src_push (GST_SRC (element)); + DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source %s done\n", name); + } } else if (GST_IS_CONNECTION (element) && argc == 1) { while (1) { DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of connection %s\n", name); @@ -564,6 +575,25 @@ gst_bin_pullfunc_wrapper (GstPad *pad) gst_element_get_name (GST_ELEMENT (pad->parent))); } +static void +gst_bin_pullregionfunc_wrapper (GstPad *pad, + gulong offset, + gulong size) +{ + region_struct region; + + region.offset = offset; + region.size = size; + + DEBUG("** in gst_bin_pullregionfunc_wrapper()============================= %s\n", + gst_element_get_name (GST_ELEMENT (pad->parent))); + cothread_set_data (GST_ELEMENT (pad->parent)->threadstate, "region", ®ion); + cothread_switch (GST_ELEMENT (pad->parent)->threadstate); + cothread_set_data (GST_ELEMENT (pad->parent)->threadstate, "region", NULL); + DEBUG("** out gst_bin_pullregionfunc_wrapper()============================= %s\n", + gst_element_get_name (GST_ELEMENT (pad->parent))); +} + static void gst_bin_pushfunc_wrapper (GstPad *pad) { @@ -683,6 +713,7 @@ gst_bin_create_plan_func (GstBin *bin) pad->pushfunc = gst_bin_pushfunc_wrapper; } pad->pullfunc = gst_bin_pullfunc_wrapper; + pad->pullregionfunc = gst_bin_pullregionfunc_wrapper; /* we only worry about sink pads */ if (gst_pad_get_direction (pad) == GST_PAD_SINK) { @@ -704,6 +735,7 @@ gst_bin_create_plan_func (GstBin *bin) opad->pushfunc = gst_bin_pushfunc_wrapper; opad->pullfunc = gst_bin_pullfunc_wrapper; + opad->pullregionfunc = gst_bin_pullregionfunc_wrapper; if (outside->threadstate == NULL) { outside->threadstate = cothread_create (bin->threadcontext); diff --git a/gst/gstpad.c b/gst/gstpad.c index 54f621cbcd..a805d4d02a 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -85,6 +85,7 @@ gst_pad_init (GstPad *pad) pad->peer = NULL; pad->chainfunc = NULL; pad->pullfunc = NULL; + pad->pullregionfunc = NULL; pad->pushfunc = NULL; pad->qosfunc = NULL; pad->parent = NULL; @@ -241,7 +242,6 @@ gst_pad_push (GstPad *pad, // first check to see if there's a push handler if (pad->pushfunc != NULL) { - //g_print("-- gst_pad_push(): putting buffer in pen and calling push handler\n"); // put the buffer in peer's holding pen pad->peer->bufpen = buffer; // now inform the handler that the peer pad has something @@ -269,20 +269,13 @@ GstBuffer* gst_pad_pull (GstPad *pad) { GstBuffer *buf; -// GstElement *peerparent; -// cothread_state *state; g_return_val_if_fail(pad != NULL, NULL); g_return_val_if_fail(GST_IS_PAD(pad), NULL); -// g_print("-- gst_pad_pull(): attempting to pull buffer\n"); - -// g_return_val_if_fail(pad->pullfunc != NULL, NULL); - // if no buffer in pen and there's a pull handler, fire it if (pad->bufpen == NULL) { if (pad->pullfunc != NULL) { -// g_print("-- gst_pad_pull(): calling pull handler\n"); (pad->pullfunc)(pad->peer); } else { g_print("-- gst_pad_pull(%s:%s): no buffer in pen, and no handler to get one there!!!\n", @@ -292,7 +285,6 @@ gst_pad_pull (GstPad *pad) // if there's a buffer in the holding pen, use it if (pad->bufpen != NULL) { -// g_print("-- gst_pad_pull(): buffer available, pulling\n"); buf = pad->bufpen; pad->bufpen = NULL; return buf; @@ -321,8 +313,38 @@ gst_pad_pull_region (GstPad *pad, gulong offset, gulong size) { - // FIXME - return gst_pad_pull (pad); + GstBuffer *buf; + + g_return_val_if_fail(pad != NULL, NULL); + g_return_val_if_fail(GST_IS_PAD(pad), NULL); + + DEBUG("-- gst_pad_pull_region(%s:%s): region (%lu,%lu)\n", + GST_ELEMENT(pad->parent)->name, pad->peer->name, + offset, size); + + // if no buffer in pen and there's a pull handler, fire it + if (pad->bufpen == NULL) { + if (pad->pullregionfunc != NULL) { + (pad->pullregionfunc)(pad->peer, offset, size); + } else { + g_print("-- gst_pad_pull_region(%s:%s): no buffer in pen, and no handler to get one there!!!\n", + GST_ELEMENT(pad->parent)->name, pad->name); + } + } + + // if there's a buffer in the holding pen, use it + if (pad->bufpen != NULL) { + buf = pad->bufpen; + pad->bufpen = NULL; + return buf; + // else we have a big problem... + } else { + g_print("-- gst_pad_pull_region(%s:%s): no buffer in pen, and no handler\n", + GST_ELEMENT(pad->parent)->name, pad->peer->name); + return NULL; + } + + return NULL; } /** diff --git a/gst/gstpad.h b/gst/gstpad.h index beff918982..5bd632c86d 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -50,6 +50,7 @@ typedef struct _GstPadClass GstPadClass; * buf is the buffer being passed */ typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf); typedef void (*GstPadPullFunction) (GstPad *pad); +typedef void (*GstPadPullRegionFunction) (GstPad *pad, gulong offset, gulong size); typedef void (*GstPadPushFunction) (GstPad *pad); typedef void (*GstPadQoSFunction) (GstPad *pad, glong qos_message); @@ -73,6 +74,7 @@ struct _GstPad { GstPadChainFunction chainfunc; GstPadPullFunction pullfunc; + GstPadPullRegionFunction pullregionfunc; GstPadPushFunction pushfunc; GstPadQoSFunction qosfunc; diff --git a/gst/gstutils.c b/gst/gstutils.c index 2d2c32ea27..bac353333b 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -152,14 +152,14 @@ void gst_util_dump_mem(guchar *mem, guint size) { i = j =0; while (iuri = NULL; priv->offset_element = NULL; priv->bit_rate_element = NULL; + priv->media_time_element = NULL; } GstPlay * @@ -165,6 +166,7 @@ static void gst_play_eos (GstElement *element, GstPlay *play) { + g_print("gstplay: eos reached\n"); gst_play_stop(play); } @@ -227,8 +229,14 @@ gst_play_object_added (GstElement *pipeline, } else { // first come first serve here... - if (!priv->offset_element) gst_play_object_introspect(element, "offset", &priv->offset_element); - if (!priv->bit_rate_element) gst_play_object_introspect(element, "bit_rate", &priv->bit_rate_element); + if (!priv->offset_element) + gst_play_object_introspect (element, "offset", &priv->offset_element); + if (!priv->bit_rate_element) + gst_play_object_introspect (element, "bit_rate", &priv->bit_rate_element); + if (!priv->media_time_element) + gst_play_object_introspect (element, "media_time", &priv->media_time_element); + if (!priv->current_time_element) + gst_play_object_introspect (element, "current_time", &priv->current_time_element); } } @@ -251,7 +259,7 @@ gst_play_set_uri (GstPlay *play, priv->uri = g_strdup (uri); - priv->src = gst_elementfactory_make ("disksrc", "disk_src"); + priv->src = gst_elementfactory_make ("asyncdisksrc", "disk_src"); g_return_val_if_fail (priv->src != NULL, -1); gtk_object_set (GTK_OBJECT (priv->src),"location",uri,NULL); gtk_signal_connect (GTK_OBJECT (priv->src), "eos", GTK_SIGNAL_FUNC (gst_play_eos), play); @@ -398,6 +406,10 @@ gst_play_get_media_total_time (GstPlay *play) priv = (GstPlayPrivate *)play->priv; + if (priv->media_time_element) { + return gst_util_get_long_arg (GTK_OBJECT (priv->media_time_element), "media_time"); + } + if (priv->bit_rate_element == NULL) return 0; bit_rate = gst_util_get_long_arg (GTK_OBJECT (priv->bit_rate_element), "bit_rate"); @@ -421,6 +433,10 @@ gst_play_get_media_current_time (GstPlay *play) priv = (GstPlayPrivate *)play->priv; + if (priv->current_time_element) { + return gst_util_get_long_arg (GTK_OBJECT (priv->current_time_element), "current_time"); + } + if (priv->bit_rate_element == NULL) return 0; bit_rate = gst_util_get_long_arg (GTK_OBJECT (priv->bit_rate_element), "bit_rate"); diff --git a/gstplay/gstplayprivate.h b/gstplay/gstplayprivate.h index 184d877280..66b7b4dd9c 100644 --- a/gstplay/gstplayprivate.h +++ b/gstplay/gstplayprivate.h @@ -23,6 +23,8 @@ struct _GstPlayPrivate { GstElement *offset_element; GstElement *bit_rate_element; + GstElement *media_time_element; + GstElement *current_time_element; }; #endif /* __GSTPLAY_PRIVATE_H__ */ diff --git a/libs/riff/gstriff.h b/libs/riff/gstriff.h index 7d586d6fb5..5bbb642660 100644 --- a/libs/riff/gstriff.h +++ b/libs/riff/gstriff.h @@ -22,9 +22,7 @@ #define __GST_RIFF_H__ -#include -#include - +#include typedef enum { GST_RIFF_OK = 0, @@ -311,18 +309,30 @@ struct _gst_riff_chunk { guint32 size; }; -typedef struct _gst_riff_riff gst_riff_riff; -typedef struct _gst_riff_list gst_riff_list; -typedef struct _gst_riff_chunk gst_riff_chunk; +struct _gst_riff_index_entry { + guint32 id; + guint32 flags; +#define GST_RIFF_IF_LIST (0x00000001L) +#define GST_RIFF_IF_KEYFRAME (0x00000010L) +#define GST_RIFF_IF_NO_TIME (0x00000100L) +#define GST_RIFF_IF_COMPUSE (0x0FFF0000L) + guint32 offset; + guint32 size; +}; -typedef struct _gst_riff_avih gst_riff_avih; -typedef struct _gst_riff_strh gst_riff_strh; -typedef struct _gst_riff_strf_vids gst_riff_strf_vids; -typedef struct _gst_riff_strf_auds gst_riff_strf_auds; -typedef struct _GstRiff GstRiff; -typedef struct _GstRiffChunk GstRiffChunk; +typedef struct _gst_riff_riff gst_riff_riff; +typedef struct _gst_riff_list gst_riff_list; +typedef struct _gst_riff_chunk gst_riff_chunk; +typedef struct _gst_riff_index_entry gst_riff_index_entry; -typedef void (*GstRiffCallback) (GstRiffChunk *chunk, gpointer data); +typedef struct _gst_riff_avih gst_riff_avih; +typedef struct _gst_riff_strh gst_riff_strh; +typedef struct _gst_riff_strf_vids gst_riff_strf_vids; +typedef struct _gst_riff_strf_auds gst_riff_strf_auds; +typedef struct _GstRiff GstRiff; +typedef struct _GstRiffChunk GstRiffChunk; + +typedef void (*GstRiffCallback) (GstRiffChunk *chunk, gpointer data); struct _GstRiff { guint32 form; @@ -358,22 +368,25 @@ struct _GstRiffChunk { /* from gstriffparse.c */ -GstRiff *gst_riff_parser_new(GstRiffCallback function, gpointer data); -GstRiffReturn gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off); +GstRiff* gst_riff_parser_new (GstRiffCallback function, gpointer data); +GstRiffReturn gst_riff_parser_next_buffer (GstRiff *riff, GstBuffer *buf, gulong off); +void gst_riff_parser_resync (GstRiff *riff, gulong offset); /* from gstriffencode.c */ -GstRiff *gst_riff_encoder_new(guint32 type); -GstRiffReturn gst_riff_encoder_avih(GstRiff *riff, gst_riff_avih *head, gulong size); -GstRiffReturn gst_riff_encoder_strh(GstRiff *riff, guint32 fcc_type, gst_riff_strh *head, gulong size); -GstRiffReturn gst_riff_encoder_strf(GstRiff *riff, void *format, gulong size); -GstRiffReturn gst_riff_encoder_chunk(GstRiff *riff, guint32 chunk_type, void *chunk, gulong size); +GstRiff* gst_riff_encoder_new (guint32 type); +GstRiffReturn gst_riff_encoder_avih (GstRiff *riff, gst_riff_avih *head, gulong size); +GstRiffReturn gst_riff_encoder_strh (GstRiff *riff, guint32 fcc_type, + gst_riff_strh *head, gulong size); +GstRiffReturn gst_riff_encoder_strf (GstRiff *riff, void *format, gulong size); +GstRiffReturn gst_riff_encoder_chunk (GstRiff *riff, guint32 chunk_type, + void *chunk, gulong size); -GstBuffer *gst_riff_encoder_get_buffer(GstRiff *riff); -GstBuffer *gst_riff_encoder_get_and_reset_buffer(GstRiff *riff); +GstBuffer* gst_riff_encoder_get_buffer (GstRiff *riff); +GstBuffer* gst_riff_encoder_get_and_reset_buffer (GstRiff *riff); /* from gstriffutil.c */ -gulong gst_riff_fourcc_to_id(gchar *fourcc); -gchar *gst_riff_id_to_fourcc(gulong id); +gulong gst_riff_fourcc_to_id (gchar *fourcc); +gchar* gst_riff_id_to_fourcc (gulong id); #endif /* __GST_RIFF_H__ */ diff --git a/libs/riff/gstriffparse.c b/libs/riff/gstriffparse.c index 3c109b9c2c..f1ae5679a9 100644 --- a/libs/riff/gstriffparse.c +++ b/libs/riff/gstriffparse.c @@ -21,7 +21,9 @@ #include #include -GstRiff *gst_riff_parser_new(GstRiffCallback function, gpointer data) { +GstRiff* +gst_riff_parser_new (GstRiffCallback function, gpointer data) +{ GstRiff *riff; riff = (GstRiff *)g_malloc(sizeof(GstRiff)); @@ -40,7 +42,9 @@ GstRiff *gst_riff_parser_new(GstRiffCallback function, gpointer data) { return riff; } -gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { +gint +gst_riff_parser_next_buffer (GstRiff *riff, GstBuffer *buf, gulong off) +{ gulong last, size; GstRiffChunk *chunk; @@ -131,12 +135,12 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { DEBUG("gst_riff_parser: next 0x%08x offset 0x%08lx size 0x%08x\n",riff->nextlikely, chunk->offset, chunk->size); - if (riff->nextlikely >= chunk->offset+chunk->size) { + if (riff->nextlikely >= chunk->offset+chunk->size) { DEBUG("gst_riff_parser: found END LIST\n"); - // we have the end of the chunk on the stack, remove it - riff->chunks = g_list_remove(riff->chunks, chunk); + // we have the end of the chunk on the stack, remove it + riff->chunks = g_list_remove(riff->chunks, chunk); } - else break; + else break; } DEBUG("gst_riff_parser: next likely chunk is at offset 0x%08x\n",riff->nextlikely); @@ -172,10 +176,10 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */ // if this buffer is incomplete if (riff->nextlikely > last) { - guint left = size - (riff->nextlikely - chunk->size - off); + guint left = size - (riff->nextlikely - chunk->size - off); DEBUG("make incomplete buffer %08x\n", left); - chunk->data = g_malloc(chunk->size); + chunk->data = g_malloc(chunk->size); memcpy(chunk->data, (gchar *)(words+2), left); riff->incomplete_chunk = chunk; riff->incomplete_chunk_size = left; @@ -207,3 +211,10 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { return 0; } +void +gst_riff_parser_resync (GstRiff *riff, gulong offset) +{ + riff->incomplete_chunk = NULL; + riff->dataleft = NULL; + riff->nextlikely = offset; +} diff --git a/plugins/elements/Makefile.am b/plugins/elements/Makefile.am index 5c6a39c37b..bf57b271ca 100644 --- a/plugins/elements/Makefile.am +++ b/plugins/elements/Makefile.am @@ -42,7 +42,7 @@ noinst_HEADERS = \ gsttypefind.h \ gstsinesrc.h -CFLAGS += -g -O2 -Wall +CFLAGS += -O2 -Wall libgstelements_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(GHTTP_LIBS) libgstelements_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE) diff --git a/plugins/elements/gstasyncdisksrc.c b/plugins/elements/gstasyncdisksrc.c index 3bb7fab4ba..57cc0dc0f3 100644 --- a/plugins/elements/gstasyncdisksrc.c +++ b/plugins/elements/gstasyncdisksrc.c @@ -51,22 +51,24 @@ enum { }; -static void gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass); -static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc); -static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id); -static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_asyncdisksrc_class_init (GstAsyncDiskSrcClass *klass); +static void gst_asyncdisksrc_init (GstAsyncDiskSrc *asyncdisksrc); -static void gst_asyncdisksrc_push(GstSrc *src); -static void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset, - gulong size); -static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element); +static void gst_asyncdisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_asyncdisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); + +static void gst_asyncdisksrc_push (GstSrc *src); +static void gst_asyncdisksrc_push_region (GstSrc *src, gulong offset, gulong size); + +static GstElementStateReturn gst_asyncdisksrc_change_state (GstElement *element); static GstSrcClass *parent_class = NULL; //static guint gst_asyncdisksrc_signals[LAST_SIGNAL] = { 0 }; GtkType -gst_asyncdisksrc_get_type(void) { +gst_asyncdisksrc_get_type(void) +{ static GtkType asyncdisksrc_type = 0; if (!asyncdisksrc_type) { @@ -80,13 +82,14 @@ gst_asyncdisksrc_get_type(void) { (GtkArgGetFunc)gst_asyncdisksrc_get_arg, (GtkClassInitFunc)NULL, }; - asyncdisksrc_type = gtk_type_unique(GST_TYPE_SRC,&asyncdisksrc_info); + asyncdisksrc_type = gtk_type_unique (GST_TYPE_SRC, &asyncdisksrc_info); } return asyncdisksrc_type; } static void -gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass) { +gst_asyncdisksrc_class_init (GstAsyncDiskSrcClass *klass) +{ GtkObjectClass *gtkobject_class; GstElementClass *gstelement_class; GstSrcClass *gstsrc_class; @@ -95,31 +98,33 @@ gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass) { gstelement_class = (GstElementClass*)klass; gstsrc_class = (GstSrcClass*)klass; - parent_class = gtk_type_class(GST_TYPE_SRC); + parent_class = gtk_type_class (GST_TYPE_SRC); - gtk_object_add_arg_type("GstAsyncDiskSrc::location", GST_TYPE_FILENAME, - GTK_ARG_READWRITE, ARG_LOCATION); - gtk_object_add_arg_type("GstAsyncDiskSrc::bytesperread", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_BYTESPERREAD); - gtk_object_add_arg_type("GstAsyncDiskSrc::offset", GTK_TYPE_LONG, - GTK_ARG_READWRITE, ARG_OFFSET); - gtk_object_add_arg_type("GstAsyncDiskSrc::size", GTK_TYPE_LONG, - GTK_ARG_READABLE, ARG_SIZE); + gtk_object_add_arg_type ("GstAsyncDiskSrc::location", GST_TYPE_FILENAME, + GTK_ARG_READWRITE, ARG_LOCATION); + gtk_object_add_arg_type ("GstAsyncDiskSrc::bytesperread", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_BYTESPERREAD); + gtk_object_add_arg_type ("GstAsyncDiskSrc::offset", GTK_TYPE_LONG, + GTK_ARG_READWRITE, ARG_OFFSET); + gtk_object_add_arg_type ("GstAsyncDiskSrc::size", GTK_TYPE_LONG, + GTK_ARG_READABLE, ARG_SIZE); gtkobject_class->set_arg = gst_asyncdisksrc_set_arg; gtkobject_class->get_arg = gst_asyncdisksrc_get_arg; gstelement_class->change_state = gst_asyncdisksrc_change_state; - gstsrc_class->push = gst_asyncdisksrc_push; - gstsrc_class->push_region = gst_asyncdisksrc_push_region; + gstsrc_class->push = gst_asyncdisksrc_push; + gstsrc_class->push_region = gst_asyncdisksrc_push_region; } -static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc) { - GST_SRC_SET_FLAGS(asyncdisksrc,GST_SRC_ASYNC); +static void +gst_asyncdisksrc_init (GstAsyncDiskSrc *asyncdisksrc) +{ + GST_SRC_SET_FLAGS (asyncdisksrc, GST_SRC_ASYNC); - asyncdisksrc->srcpad = gst_pad_new("src",GST_PAD_SRC); - gst_element_add_pad(GST_ELEMENT(asyncdisksrc),asyncdisksrc->srcpad); + asyncdisksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_element_add_pad (GST_ELEMENT (asyncdisksrc), asyncdisksrc->srcpad); asyncdisksrc->filename = NULL; asyncdisksrc->fd = 0; @@ -128,61 +133,69 @@ static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc) { asyncdisksrc->curoffset = 0; asyncdisksrc->bytes_per_read = 4096; asyncdisksrc->seq = 0; + asyncdisksrc->new_seek = FALSE; } -static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { +static void +gst_asyncdisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +{ GstAsyncDiskSrc *src; /* it's not null if we got it, but it might not be ours */ - g_return_if_fail(GST_IS_ASYNCDISKSRC(object)); - src = GST_ASYNCDISKSRC(object); + g_return_if_fail (GST_IS_ASYNCDISKSRC (object)); + + src = GST_ASYNCDISKSRC (object); switch(id) { case ARG_LOCATION: /* the element must be stopped in order to do this */ - g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); + g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING); - if (src->filename) g_free(src->filename); + if (src->filename) g_free (src->filename); /* clear the filename if we get a NULL (is that possible?) */ - if (GTK_VALUE_STRING(*arg) == NULL) { - gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); + if (GTK_VALUE_STRING (*arg) == NULL) { + gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); src->filename = NULL; /* otherwise set the new filename */ } else { - src->filename = g_strdup(GTK_VALUE_STRING(*arg)); + src->filename = g_strdup (GTK_VALUE_STRING (*arg)); } break; case ARG_BYTESPERREAD: - src->bytes_per_read = GTK_VALUE_INT(*arg); + src->bytes_per_read = GTK_VALUE_INT (*arg); break; case ARG_OFFSET: - src->curoffset = GTK_VALUE_LONG(*arg); + src->curoffset = GTK_VALUE_LONG (*arg); + src->new_seek = TRUE; break; default: break; } } -static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { +static void +gst_asyncdisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +{ GstAsyncDiskSrc *src; /* it's not null if we got it, but it might not be ours */ - g_return_if_fail(GST_IS_ASYNCDISKSRC(object)); - src = GST_ASYNCDISKSRC(object); + g_return_if_fail (GST_IS_ASYNCDISKSRC (object)); + + src = GST_ASYNCDISKSRC (object); switch (id) { case ARG_LOCATION: - GTK_VALUE_STRING(*arg) = src->filename; + GTK_VALUE_STRING (*arg) = src->filename; break; case ARG_BYTESPERREAD: - GTK_VALUE_INT(*arg) = src->bytes_per_read; + GTK_VALUE_INT (*arg) = src->bytes_per_read; break; case ARG_OFFSET: - GTK_VALUE_LONG(*arg) = src->curoffset; + GTK_VALUE_LONG (*arg) = src->curoffset; break; case ARG_SIZE: - GTK_VALUE_LONG(*arg) = src->size; + GTK_VALUE_LONG (*arg) = src->size; break; default: arg->type = GTK_TYPE_INVALID; @@ -196,43 +209,51 @@ static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { * * Push a new buffer from the asyncdisksrc at the current offset. */ -void gst_asyncdisksrc_push(GstSrc *src) { +static void +gst_asyncdisksrc_push (GstSrc *src) +{ GstAsyncDiskSrc *asyncdisksrc; GstBuffer *buf; - g_return_if_fail(src != NULL); - g_return_if_fail(GST_IS_ASYNCDISKSRC(src)); - g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN)); - asyncdisksrc = GST_ASYNCDISKSRC(src); + g_return_if_fail (src != NULL); + g_return_if_fail (GST_IS_ASYNCDISKSRC (src)); + g_return_if_fail (GST_FLAG_IS_SET (src, GST_ASYNCDISKSRC_OPEN)); + + asyncdisksrc = GST_ASYNCDISKSRC (src); /* deal with EOF state */ if (asyncdisksrc->curoffset >= asyncdisksrc->size) { - gst_src_signal_eos(GST_SRC(asyncdisksrc)); + gst_src_signal_eos (GST_SRC (asyncdisksrc)); return; } /* create the buffer */ // FIXME: should eventually use a bufferpool for this - buf = gst_buffer_new(); - g_return_if_fail(buf != NULL); + buf = gst_buffer_new (); + + g_return_if_fail (buf != NULL); /* simply set the buffer to point to the correct region of the file */ - GST_BUFFER_DATA(buf) = asyncdisksrc->map + asyncdisksrc->curoffset; - GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset; - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_DONTFREE); + GST_BUFFER_DATA (buf) = asyncdisksrc->map + asyncdisksrc->curoffset; + GST_BUFFER_OFFSET (buf) = asyncdisksrc->curoffset; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if ((asyncdisksrc->curoffset + asyncdisksrc->bytes_per_read) > asyncdisksrc->size) { - GST_BUFFER_SIZE(buf) = asyncdisksrc->size - asyncdisksrc->curoffset; + GST_BUFFER_SIZE (buf) = asyncdisksrc->size - asyncdisksrc->curoffset; // FIXME: set the buffer's EOF bit here } else - GST_BUFFER_SIZE(buf) = asyncdisksrc->bytes_per_read; - asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf); + GST_BUFFER_SIZE (buf) = asyncdisksrc->bytes_per_read; - //gst_buffer_ref(buf); + asyncdisksrc->curoffset += GST_BUFFER_SIZE (buf); + + if (asyncdisksrc->new_seek) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH); + asyncdisksrc->new_seek = FALSE; + } /* we're done, push the buffer off now */ - gst_pad_push(asyncdisksrc->srcpad,buf); + gst_pad_push (asyncdisksrc->srcpad, buf); } /** @@ -243,78 +264,84 @@ void gst_asyncdisksrc_push(GstSrc *src) { * * Push a new buffer from the asyncdisksrc of given size at given offset. */ -void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) { +static void +gst_asyncdisksrc_push_region (GstSrc *src, gulong offset, gulong size) +{ GstAsyncDiskSrc *asyncdisksrc; GstBuffer *buf; - g_return_if_fail(src != NULL); - g_return_if_fail(GST_IS_ASYNCDISKSRC(src)); - g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_READY)); - asyncdisksrc = GST_ASYNCDISKSRC(src); + g_return_if_fail (src != NULL); + g_return_if_fail (GST_IS_ASYNCDISKSRC (src)); + g_return_if_fail (GST_FLAG_IS_SET (src, GST_ASYNCDISKSRC_OPEN)); + + asyncdisksrc = GST_ASYNCDISKSRC (src); /* deal with EOF state */ if (offset >= asyncdisksrc->size) { - gst_src_signal_eos(GST_SRC(asyncdisksrc)); + gst_src_signal_eos (GST_SRC (asyncdisksrc)); return; } /* create the buffer */ // FIXME: should eventually use a bufferpool for this - buf = gst_buffer_new(); - g_return_if_fail(buf); + buf = gst_buffer_new (); + g_return_if_fail (buf); /* simply set the buffer to point to the correct region of the file */ - GST_BUFFER_DATA(buf) = asyncdisksrc->map + offset; - GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset; - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_DONTFREE); + GST_BUFFER_DATA (buf) = asyncdisksrc->map + offset; + GST_BUFFER_OFFSET (buf) = offset; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); if ((offset + size) > asyncdisksrc->size) { - GST_BUFFER_SIZE(buf) = asyncdisksrc->size - offset; + GST_BUFFER_SIZE (buf) = asyncdisksrc->size - offset; // FIXME: set the buffer's EOF bit here } else - GST_BUFFER_SIZE(buf) = size; - asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf); + GST_BUFFER_SIZE (buf) = size; /* we're done, push the buffer off now */ - gst_pad_push(asyncdisksrc->srcpad,buf); + gst_pad_push (asyncdisksrc->srcpad,buf); } /* open the file and mmap it, necessary to go to READY state */ -static gboolean gst_asyncdisksrc_open_file(GstAsyncDiskSrc *src) { - g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN), FALSE); +static +gboolean gst_asyncdisksrc_open_file (GstAsyncDiskSrc *src) +{ + g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_ASYNCDISKSRC_OPEN), FALSE); /* open the file */ - src->fd = open(src->filename,O_RDONLY); + src->fd = open (src->filename, O_RDONLY); if (src->fd < 0) { - gst_element_error(GST_ELEMENT(src),"opening file"); + gst_element_error (GST_ELEMENT (src), "opening file"); return FALSE; } else { /* find the file length */ - src->size = lseek(src->fd,0,SEEK_END); - lseek(src->fd,0,SEEK_SET); + src->size = lseek (src->fd, 0, SEEK_END); + lseek (src->fd, 0, SEEK_SET); /* map the file into memory */ - src->map = mmap(NULL,src->size,PROT_READ,MAP_SHARED,src->fd,0); - madvise(src->map,src->size,2); + 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) { - close(src->fd); - gst_element_error(GST_ELEMENT(src),"mmapping file"); + close (src->fd); + gst_element_error (GST_ELEMENT (src),"mmapping file"); return FALSE; } - GST_FLAG_SET(src,GST_ASYNCDISKSRC_OPEN); + GST_FLAG_SET (src, GST_ASYNCDISKSRC_OPEN); } return TRUE; } /* unmap and close the file */ -static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) { - g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN)); +static void +gst_asyncdisksrc_close_file (GstAsyncDiskSrc *src) +{ + g_return_if_fail (GST_FLAG_IS_SET (src, GST_ASYNCDISKSRC_OPEN)); /* unmap the file from memory */ - munmap(src->map,src->size); + munmap (src->map, src->size); /* close the file */ - close(src->fd); + close (src->fd); /* zero out a lot of our state */ src->fd = 0; @@ -323,25 +350,27 @@ static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) { src->curoffset = 0; src->seq = 0; - GST_FLAG_UNSET(src,GST_ASYNCDISKSRC_OPEN); + GST_FLAG_UNSET (src, GST_ASYNCDISKSRC_OPEN); } -static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element) { - g_return_val_if_fail(GST_IS_ASYNCDISKSRC(element),GST_STATE_FAILURE); +static +GstElementStateReturn gst_asyncdisksrc_change_state (GstElement *element) +{ + g_return_val_if_fail (GST_IS_ASYNCDISKSRC (element), GST_STATE_FAILURE); - if (GST_STATE_PENDING(element) == GST_STATE_NULL) { - if (GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) - gst_asyncdisksrc_close_file(GST_ASYNCDISKSRC(element)); + if (GST_STATE_PENDING (element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET (element, GST_ASYNCDISKSRC_OPEN)) + gst_asyncdisksrc_close_file (GST_ASYNCDISKSRC (element)); } else { - if (!GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) { - if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element))) + if (!GST_FLAG_IS_SET (element, GST_ASYNCDISKSRC_OPEN)) { + if (!gst_asyncdisksrc_open_file (GST_ASYNCDISKSRC (element))) return GST_STATE_FAILURE; } } - if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element); + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); return GST_STATE_SUCCESS; } diff --git a/plugins/elements/gstasyncdisksrc.h b/plugins/elements/gstasyncdisksrc.h index 6add9425b9..60a9976f1a 100644 --- a/plugins/elements/gstasyncdisksrc.h +++ b/plugins/elements/gstasyncdisksrc.h @@ -70,6 +70,7 @@ struct _GstAsyncDiskSrc { /* details for fallback synchronous read */ gulong curoffset; /* current offset in file */ gulong bytes_per_read; /* bytes per read */ + gboolean new_seek; gulong seq; /* buffer sequence number */ }; diff --git a/plugins/elements/gstdisksrc.c b/plugins/elements/gstdisksrc.c index fc50da5acf..51efc3786d 100644 --- a/plugins/elements/gstdisksrc.c +++ b/plugins/elements/gstdisksrc.c @@ -52,16 +52,17 @@ enum { }; -static void gst_disksrc_class_init(GstDiskSrcClass *klass); -static void gst_disksrc_init(GstDiskSrc *disksrc); -static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id); -static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_disksrc_class_init (GstDiskSrcClass *klass); +static void gst_disksrc_init (GstDiskSrc *disksrc); -static void gst_disksrc_close_file(GstDiskSrc *src); +static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_disksrc_push(GstSrc *src); -//static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size); -static GstElementStateReturn gst_disksrc_change_state(GstElement *element); +static void gst_disksrc_close_file (GstDiskSrc *src); + +static void gst_disksrc_push (GstSrc *src); + +static GstElementStateReturn gst_disksrc_change_state (GstElement *element); static GstSrcClass *parent_class = NULL; @@ -104,7 +105,7 @@ gst_disksrc_class_init(GstDiskSrcClass *klass) { gtk_object_add_arg_type("GstDiskSrc::bytesperread", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_BYTESPERREAD); gtk_object_add_arg_type("GstDiskSrc::offset", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_OFFSET); + GTK_ARG_READABLE, ARG_OFFSET); gtk_object_add_arg_type("GstDiskSrc::size", GTK_TYPE_INT, GTK_ARG_READABLE, ARG_SIZE); @@ -157,11 +158,13 @@ static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { case ARG_BYTESPERREAD: src->bytes_per_read = GTK_VALUE_INT(*arg); break; + /* case ARG_OFFSET: src->curoffset = GTK_VALUE_INT(*arg); lseek(src->fd,src->curoffset, SEEK_SET); src->new_seek = TRUE; break; + */ default: break; }