Added seeking to the avi decoder by implementing pull_region.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 6 Nov 2000 00:15:51 +0000 (00:15 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 6 Nov 2000 00:15:51 +0000 (00:15 +0000)
Original commit message from CVS:
Added seeking to the avi decoder by implementing pull_region.
Fixes to the asyncdisksrc.
Added thread specific data to the cothreads.

18 files changed:
gst/cothreads.c
gst/cothreads.h
gst/elements/Makefile.am
gst/elements/gstasyncdisksrc.c
gst/elements/gstasyncdisksrc.h
gst/elements/gstdisksrc.c
gst/gstbin.c
gst/gstpad.c
gst/gstpad.h
gst/gstutils.c
gstplay/gstplay.c
gstplay/gstplayprivate.h
libs/riff/gstriff.h
libs/riff/gstriffparse.c
plugins/elements/Makefile.am
plugins/elements/gstasyncdisksrc.c
plugins/elements/gstasyncdisksrc.h
plugins/elements/gstdisksrc.c

index 44feacf..8d0260a 100644 (file)
@@ -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) 
 {
index 57ba546..e09cbba 100644 (file)
@@ -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__ */
index 5c6a39c..bf57b27 100644 (file)
@@ -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)
index 3bb7fab..57cc0dc 100644 (file)
@@ -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;
 }
index 6add942..60a9976 100644 (file)
@@ -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 */
 };
index fc50da5..51efc37 100644 (file)
@@ -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;
   }
index f691a3f..41c7d5b 100644 (file)
@@ -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);
@@ -565,6 +576,25 @@ gst_bin_pullfunc_wrapper (GstPad *pad)
 }
 
 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", &region);
+  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) 
 {
   DEBUG("** in gst_bin_pushfunc_wrapper()============================= %s\n",
@@ -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);
index 54f621c..a805d4d 100644 (file)
@@ -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;
 }
 
 /**
index beff918..5bd632c 100644 (file)
@@ -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;
 
index 2d2c32e..bac3533 100644 (file)
@@ -152,14 +152,14 @@ void gst_util_dump_mem(guchar *mem, guint size) {
 
   i = j =0;
   while (i<size) {
-    g_print("%02x ", mem[i]);
-    if (j == 16) {
-      g_print("\n");
-      j = 0;
+    if (j == 0) {
+      g_print("\n%08x : ", i);
+      j = 15;
     }
     else {
-      j++;
+      j--;
     }
+    g_print("%02x ", mem[i]);
     i++;
   }
   g_print("\n");
index 7e74dad..2a939b1 100644 (file)
@@ -153,6 +153,7 @@ gst_play_init (GstPlay *play)
   priv->uri = 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");
index 184d877..66b7b4d 100644 (file)
@@ -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__ */
index 7d586d6..5bbb642 100644 (file)
@@ -22,9 +22,7 @@
 #define __GST_RIFF_H__
 
 
-#include <gst/gstbuffer.h>
-#include <gst/gstplugin.h>
-
+#include <gst/gst.h>
 
 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_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 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_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);
+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__ */
index 3c109b9..f1ae567 100644 (file)
@@ -21,7 +21,9 @@
 #include <gst/gst.h>
 #include <gstriff.h>
 
-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;
+}
index 5c6a39c..bf57b27 100644 (file)
@@ -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)
index 3bb7fab..57cc0dc 100644 (file)
@@ -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;
 }
index 6add942..60a9976 100644 (file)
@@ -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 */
 };
index fc50da5..51efc37 100644 (file)
@@ -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;
   }