--- gstavidemux.h.orig	2006-03-29 12:06:05.000000000 +0300
+++ gstavidemux.h	2006-03-29 12:08:14.000000000 +0300
@@ -1,5 +1,6 @@
 /* GStreamer
  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2006> Nokia Corporation.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,6 +26,7 @@
 #include "avi-ids.h"
 #include "gst/riff/riff-ids.h"
 #include "gst/riff/riff-read.h"
+#include <gst/base/gstadapter.h>
 
 G_BEGIN_DECLS
 
@@ -91,6 +93,15 @@
   GST_AVI_DEMUX_MOVI,
 } GstAviDemuxState;
 
+typedef enum {
+  GST_AVI_DEMUX_HEADER_TAG_LIST,
+  GST_AVI_DEMUX_HEADER_AVIH,
+  GST_AVI_DEMUX_HEADER_ELEMENTS,
+  GST_AVI_DEMUX_HEADER_INFO,
+  GST_AVI_DEMUX_HEADER_JUNK,
+  GST_AVI_DEMUX_HEADER_DATA
+} GstAviDemuxHeaderState;
+
 typedef struct _GstAviDemux {
   GstElement     parent;
 
@@ -99,6 +110,7 @@
 
   /* AVI decoding state */
   GstAviDemuxState state;
+  GstAviDemuxHeaderState header_state;
   guint64        offset;
 
   /* index */
@@ -113,6 +125,11 @@
   guint          num_a_streams;
   avi_stream_context stream[GST_AVI_DEMUX_MAX_STREAMS];
 
+  /* For streaming mode */
+  gboolean      streaming;
+  gboolean      have_eos;
+  GstAdapter    *adapter;
+
   /* some stream info for length */
   gst_riff_avih *avih;
 
--- gstavidemux.c.orig	2006-03-29 12:05:59.000000000 +0300
+++ gstavidemux.c	2006-03-29 12:04:25.000000000 +0300
@@ -1,5 +1,6 @@
 /* GStreamer
  * Copyright (C) <1999> Erik Walthinsen <omega@temple-baptist.com>
+ * Copyright (C) <2006> Nokia Corporation.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,6 +29,7 @@
 #include "gstavidemux.h"
 #include "avi-ids.h"
 #include <gst/gst-i18n-plugin.h>
+#include <gst/base/gstadapter.h>
 
 GST_DEBUG_CATEGORY_STATIC (avidemux_debug);
 #define GST_CAT_DEFAULT avidemux_debug
@@ -43,6 +45,7 @@
 static void gst_avi_demux_base_init (GstAviDemuxClass * klass);
 static void gst_avi_demux_class_init (GstAviDemuxClass * klass);
 static void gst_avi_demux_init (GstAviDemux * avi);
+static void gst_avi_demux_dispose (GObject * object);
 
 static void gst_avi_demux_reset (GstAviDemux * avi);
 
@@ -65,9 +68,13 @@
 static gboolean gst_avi_demux_sink_activate (GstPad * sinkpad);
 static gboolean gst_avi_demux_sink_activate_pull (GstPad * sinkpad,
     gboolean active);
+static gboolean gst_avi_demux_activate_push(GstPad  *pad, gboolean active);
+static GstFlowReturn gst_avi_demux_chain(GstPad *pad, GstBuffer *buf);
+
 static GstStateChangeReturn gst_avi_demux_change_state (GstElement * element,
     GstStateChange transition);
 
+
 static GstElementClass *parent_class = NULL;
 
 GType
@@ -132,12 +139,14 @@
 gst_avi_demux_class_init (GstAviDemuxClass * klass)
 {
   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+  GObjectClass *gobject_class = (GObjectClass *) klass;
 
   GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux",
       0, "Demuxer for AVI streams");
 
   parent_class = g_type_class_peek_parent (klass);
-
+  
+  gobject_class->dispose = gst_avi_demux_dispose;
   gstelement_class->change_state = gst_avi_demux_change_state;
 }
 
@@ -150,7 +159,10 @@
   gst_pad_set_activate_function (avi->sinkpad, gst_avi_demux_sink_activate);
   gst_pad_set_activatepull_function (avi->sinkpad,
       gst_avi_demux_sink_activate_pull);
+  gst_pad_set_activatepush_function(avi->sinkpad,
+      gst_avi_demux_activate_push);
   gst_element_add_pad (GST_ELEMENT (avi), avi->sinkpad);
+  gst_pad_set_chain_function(avi->sinkpad, gst_avi_demux_chain);
 
   gst_avi_demux_reset (avi);
 
@@ -158,6 +170,22 @@
   memset (&avi->stream, 0, sizeof (avi->stream));
 }
 
+
+static void
+gst_avi_demux_dispose (GObject * object)
+{
+  GST_DEBUG("AVI: Dispose\n");
+  GstAviDemux *avi = GST_AVI_DEMUX(object);
+
+  if ( avi->adapter ) {
+    g_object_unref(avi->adapter);
+    avi->adapter = NULL;
+  }
+
+  G_OBJECT_CLASS (parent_class)->dispose(object);
+}
+
+
 static void
 gst_avi_demux_reset (GstAviDemux * avi)
 {
@@ -192,6 +220,8 @@
   g_free (avi->avih);
   avi->avih = NULL;
 
+  avi->have_eos = FALSE;
+
   if (avi->seek_event)
     gst_event_unref (avi->seek_event);
   avi->seek_event = NULL;
@@ -245,7 +275,6 @@
   return last_entry;
 }
 
-
 #if 0
 static const GstFormat *
 gst_avi_demux_get_src_formats (GstPad * pad)
@@ -1923,6 +1952,314 @@
   return TRUE;
 }
 
+
+/*
+ * Read AVI file tag when streaming
+ */
+static GstFlowReturn
+gst_avi_demux_parse_stream_init(GstAviDemux * avi) //, GstBuffer * buf)
+{ 
+  if ( gst_adapter_available(avi->adapter) >= 12 ) {
+    GstBuffer *tmp = gst_buffer_new();
+    /* _take flushes the data */
+    GST_BUFFER_DATA(tmp) = gst_adapter_take(avi->adapter, 12);
+    GST_BUFFER_SIZE(tmp) = 12;
+
+    GST_DEBUG("Parsing avi header\n");
+    if(!gst_avi_demux_parse_file_header (GST_ELEMENT (avi), tmp)) {
+      return GST_FLOW_ERROR;
+    }
+    GST_DEBUG("header ok\n");
+    avi->offset += 12;
+    /* Go to next state */
+    avi->state = GST_AVI_DEMUX_HEADER;
+  }  
+  return GST_FLOW_OK;
+}
+
+
+/**
+ *
+ * Peek next chunk info (tag and size)
+ *
+ * @avi Avi object
+ * @tag holder for tag
+ * @size holder for tag size
+ *
+ * returns: TRUE when one chunk info has been got
+ */
+static gboolean
+gst_avi_demux_peek_chunk_info( GstAviDemux * avi, guint32 * tag, guint32 * size )
+{
+  const guint8 * data = NULL;
+  
+  if ( gst_adapter_available(avi->adapter) < 8 ) {
+    return FALSE;
+  }
+  
+  data = gst_adapter_peek(avi->adapter, 8);
+  *tag = GST_READ_UINT32_LE (data);
+  *size = GST_READ_UINT32_LE (data + 4);
+
+  return TRUE;
+}
+
+
+/**
+ *
+ * Peek enough data for one full chunk
+ *
+ * @avi Avi object
+ * @tag holder for tag
+ * @size holder for tag size
+ *
+ * returns: TRUE when one chunk has been got
+ */
+static gboolean
+gst_avi_demux_peek_chunk( GstAviDemux * avi, guint32 * tag, guint32 * size )
+{
+  const guint8 * data = NULL;
+  guint32 peek_size = 0;
+  
+  if ( gst_adapter_available(avi->adapter) < 8 ) {
+    return FALSE;
+  }
+  
+  data = gst_adapter_peek(avi->adapter, 8);
+  *tag = GST_READ_UINT32_LE (data);
+  *size = GST_READ_UINT32_LE (data + 4);
+  GST_DEBUG("Need to peek chunk of %d bytes\n", *size);
+  peek_size = (*size + 1) & ~1;
+
+  if ( gst_adapter_available(avi->adapter) >= (8 + peek_size) ) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+
+/*
+ * Read AVI headers when streaming
+ */
+ 
+static GstFlowReturn
+gst_avi_demux_parse_stream_header (GstAviDemux * avi) //, GstBuffer * buf)
+{
+  GstFlowReturn ret = GST_FLOW_OK;
+  guint32 tag = 0;
+  guint32 ltag = 0;
+  guint32 size = 0;
+  const guint8 * data;
+  GstBuffer *buf = NULL;
+  GstBuffer *sub = NULL;
+  guint offset = 4;
+
+  GST_DEBUG("Reading and parsing avi headers\n");  
+  switch (avi->header_state) {
+    case GST_AVI_DEMUX_HEADER_TAG_LIST:
+      if ( gst_avi_demux_peek_chunk(avi, &tag, &size) ) {
+        avi->offset += 8 + ((size + 1) & ~1);
+        if (tag != GST_RIFF_TAG_LIST) {
+          GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
+                             ("Invalid AVI header (no LIST at start): %"
+                                 GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
+          return GST_FLOW_ERROR;
+        }
+        gst_adapter_flush(avi->adapter, 8);
+        GST_DEBUG("Reading %d bytes\n", size);
+        buf = gst_buffer_new();
+        GST_BUFFER_DATA(buf) = gst_adapter_take(avi->adapter, size);
+        GST_BUFFER_SIZE(buf) = size;
+        if ( GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl ) {
+          GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
+                             ("Invalid AVI header (no hdrl at start): %"
+                                 GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
+          gst_buffer_unref (buf);
+          return GST_FLOW_ERROR;
+        }
+        GST_DEBUG("hdrl tag found. Parsing next chunk\n");
+
+        if (!gst_riff_parse_chunk (GST_ELEMENT (avi), buf, &offset, &tag, &sub)
+            || tag != GST_RIFF_TAG_avih) {
+          GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
+                             ("Invalid AVI header (no avih at start): %"
+                                 GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
+          if (sub) {
+            gst_buffer_unref (sub);
+            sub = NULL;
+          }
+          gst_buffer_unref (buf);
+          return GST_FLOW_ERROR;
+        } else if (!gst_avi_demux_parse_avih (GST_ELEMENT (avi), sub, &avi->avih)) {
+          gst_buffer_unref (buf);
+          return GST_FLOW_ERROR;
+        }
+
+        GST_DEBUG("AVI header ok, parsing elements next\n");
+
+        /* now, read the elements from the header until the end */
+        while (gst_riff_parse_chunk (GST_ELEMENT (avi), buf, &offset, &tag, &sub)) {
+          switch (tag) {
+            case GST_RIFF_TAG_LIST:
+              if (!sub || GST_BUFFER_SIZE (sub) < 4) {
+                if (sub) {
+                  gst_buffer_unref (sub);
+                  sub = NULL;
+                }
+                break;
+              }
+
+              switch (GST_READ_UINT32_LE (GST_BUFFER_DATA (sub))) {
+                case GST_RIFF_LIST_strl:
+                  if (!(gst_avi_demux_parse_stream (GST_ELEMENT (avi), sub)))
+                    return GST_FLOW_ERROR;
+                  gst_buffer_unref (sub);
+                  break;
+                case GST_RIFF_LIST_odml:
+                  gst_avi_demux_parse_odml (GST_ELEMENT (avi), sub);
+                  break;
+                default:
+                  GST_WARNING_OBJECT (avi,
+                                      "Unknown list %" GST_FOURCC_FORMAT " in AVI header",
+                                      GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA (sub))));
+                  /* fall-through */
+                case GST_RIFF_TAG_JUNK:
+                  if (sub) {
+                    gst_buffer_unref (sub);
+                    sub = NULL;
+                  }
+                  break;
+              }
+              break;
+            default:
+              GST_WARNING_OBJECT (avi,
+                                  "Unknown off %d tag %" GST_FOURCC_FORMAT " in AVI header",
+                                  offset, GST_FOURCC_ARGS (tag));
+              /* fall-through */
+            case GST_RIFF_TAG_JUNK:
+              if (sub) {
+                gst_buffer_unref (sub);
+                sub = NULL;
+              }
+              break;
+          }
+        }
+        gst_buffer_unref (buf);
+        GST_DEBUG("Elements parsed\n");
+        /* check parsed streams */
+        if (avi->num_streams == 0) {
+          GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL), ("No streams found"));
+          return GST_FLOW_ERROR;
+        } else if (avi->num_streams != avi->avih->streams) {
+          GST_WARNING_OBJECT (avi,
+                              "Stream header mentioned %d streams, but %d available",
+                              avi->avih->streams, avi->num_streams);
+        }
+        GST_DEBUG("Get junk and info next\n");
+        avi->header_state = GST_AVI_DEMUX_HEADER_INFO;
+      } else {
+        /* Need more data */
+        return ret;
+      }
+      /* fall-though */
+    case GST_AVI_DEMUX_HEADER_INFO:
+
+iterate:
+      if ( gst_adapter_available(avi->adapter) < 12 ) {
+        return GST_FLOW_OK;
+      }
+
+      data = gst_adapter_peek(avi->adapter, 12);
+      tag = GST_READ_UINT32_LE (data);
+      size = GST_READ_UINT32_LE (data + 4);
+      ltag = GST_READ_UINT32_LE (data + 8);
+
+      if (tag == GST_RIFF_TAG_LIST) {
+        switch (ltag) {
+          case GST_RIFF_LIST_movi:
+            /* done */
+            GST_DEBUG("Found movi chunk. Starting to stream data\n");
+
+            gst_adapter_flush(avi->adapter, 12);
+            avi->offset += 12;
+            avi->state = GST_AVI_DEMUX_MOVI;
+
+            /* send initial discont */
+            avi->segment_start = 0;
+            avi->segment_stop = (gint64) (((gfloat) avi->stream[0].strh->scale) *
+                avi->stream[0].strh->length / avi->stream[0].strh->rate) * GST_SECOND;
+            avi->seek_event = gst_event_new_new_segment
+                (FALSE, avi->segment_rate, GST_FORMAT_TIME,
+                 avi->segment_start, avi->segment_stop, avi->segment_start);
+
+            /* at this point we know all the streams and we can signal the no more
+              * pads signal */
+            GST_DEBUG("Signaling no more pads\n");
+            GST_DEBUG_OBJECT (avi, "signaling no more pads");
+            gst_element_no_more_pads (GST_ELEMENT (avi));
+
+            return GST_FLOW_OK;
+          case GST_RIFF_LIST_INFO:
+            GST_DEBUG("Found INFO chunk\n");
+            if ( gst_avi_demux_peek_chunk(avi, &tag, &size ) ) {
+              avi->offset += 12;
+              gst_adapter_flush(avi->adapter, 12);
+              buf = gst_buffer_new();
+              GST_BUFFER_DATA(buf) = gst_adapter_take(avi->adapter, size-4);
+              GST_BUFFER_SIZE(buf) = size-4;
+
+              GstTagList *t;
+
+              gst_riff_parse_info (GST_ELEMENT (avi), buf, &t);
+              if (t) {
+                GST_DEBUG("Tags found, signaling\n");
+                gst_element_found_tags (GST_ELEMENT (avi), t);
+              }
+              gst_buffer_unref (buf);
+//              gst_adapter_flush(avi->adapter, ((size + 1) & ~1) - 4);
+              avi->offset += ((size + 1) & ~1) - 4;
+              goto iterate;
+            } else {
+              /* Need more data */
+              return GST_FLOW_OK;
+            }
+
+            /* gst_riff_read_chunk() has already advanced avi->offset */
+            break;
+          default:
+            if ( gst_avi_demux_peek_chunk(avi, &tag, &size ) ) {
+              avi->offset += 8 + ((size + 1) & ~1);
+              gst_adapter_flush(avi->adapter, 8 + ((size + 1) & ~1));
+            } else {
+              /* Need more data */
+              return GST_FLOW_OK;
+            }
+            break;
+        }
+      } else {
+        if ( gst_avi_demux_peek_chunk(avi, &tag, &size ) ) {
+          avi->offset += 8 + ((size + 1) & ~1);
+          gst_adapter_flush(avi->adapter, 8 + ((size + 1) & ~1));
+          goto iterate;
+        } else {
+          /* Need more data */
+          return GST_FLOW_OK;
+        }
+      }
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+  
+}
+
+
+
+
+
 /*
  * Read full AVI headers.
  */
@@ -2336,72 +2673,130 @@
 static GstFlowReturn
 gst_avi_demux_stream_data (GstAviDemux * avi)
 {
+  guint32 tag = 0;
+  guint32 size = 0;
+  gint stream_nr = 0;
+  const guint8 * data = NULL;
+  GstFlowReturn res = GST_FLOW_OK;
+
   /* if we have a avi->index_entries[], we don't want to read
    * the stream linearly, but seek to the next ts/index_entry. */
-  //if (avi->index_entries != NULL) {
-  return gst_avi_demux_process_next_entry (avi);
-  //}
-#if 0
-  if (!gst_avi_demux_sync (avi, &tag, FALSE))
-    return FALSE;
-  stream_nr = CHUNKID_TO_STREAMNR (tag);
+  if (avi->index_entries != NULL) {
+    return gst_avi_demux_process_next_entry (avi);
+  }
 
-  if (stream_nr < 0 || stream_nr >= avi->num_streams) {
-    /* recoverable */
-    GST_WARNING ("Invalid stream ID %d (%" GST_FOURCC_FORMAT ")",
-        stream_nr, GST_FOURCC_ARGS (tag));
-    if (!gst_riff_read_skip (riff))
-      return FALSE;
-  } else {
-    avi_stream_context *stream;
-    GstClockTime next_ts;
-    GstFormat format;
-    GstBuffer *buf;
+  if ( avi->have_eos ) {
+    /* Clean adapter, we're done */
+    gst_adapter_clear(avi->adapter);
+    return res;
+  }
 
-    /* get buffer */
-    if (!gst_riff_read_data (riff, &tag, &buf))
-      return FALSE;
+/*  if (!gst_avi_demux_sync (avi, &tag, FALSE))
+    return FALSE;*/
 
-    /* get time of this buffer */
-    stream = &avi->stream[stream_nr];
-    format = GST_FORMAT_TIME;
-    gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &next_ts);
+  /* Iterate until need more data, so adapter won't grow too much */
+  while (1) {
+    if ( ! gst_avi_demux_peek_chunk_info(avi, &tag, &size) ) {
+      return res;
+    }
 
-    /* set delay (if any) */
-    if (stream->strh->init_frames == stream->current_frame &&
-        stream->delay == 0)
-      stream->delay = next_ts;
-
-    stream->current_frame++;
-    stream->current_byte += GST_BUFFER_SIZE (buf);
-
-    /* should we skip this data? */
-    if (stream->skip) {
-      stream->skip--;
-      gst_buffer_unref (buf);
+    if ( ( tag & 0xff) >= '0' &&
+         ( tag & 0xff) <= '9' &&
+         ( (tag >> 8) & 0xff) >= '0' &&
+         ( (tag >> 8) & 0xff) <= '9' ) {
+      GST_DEBUG("Chunk ok (%" GST_FOURCC_FORMAT "), size %d\n", GST_FOURCC_ARGS (tag), size);
+    } else if ( tag == GST_RIFF_TAG_idx1 ) {
+      GST_DEBUG("Found index tag, stream done\n");
+      gst_avi_demux_send_event (avi, gst_event_new_eos ());
+      avi->have_eos = TRUE;
+      return res;
     } else {
-      if (!stream->pad || !GST_PAD_IS_USABLE (stream->pad)) {
-        gst_buffer_unref (buf);
-      } else {
-        GstClockTime dur_ts;
+      GST_DEBUG("No more stream chunks, send EOS\n");
+      gst_avi_demux_send_event (avi, gst_event_new_eos ());
+      avi->have_eos = TRUE;
+      return res;
+    }
 
-        if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
-          buf = gst_avi_demux_invert (stream, buf);
-        }
+    if ( ! gst_avi_demux_peek_chunk(avi, &tag, &size) ) {
+      return res;
+    }
 
-        GST_BUFFER_TIMESTAMP (buf) = next_ts;
-        gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &dur_ts);
-        GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
-        GST_DEBUG_OBJECT (avi,
-            "Pushing buffer with time=%" GST_TIME_FORMAT " over pad %s",
-            GST_TIME_ARGS (next_ts), GST_PAD_NAME (stream->pad));
-        gst_pad_push (stream->pad, GST_DATA (buf));
-      }
+    if ( size > 0 ) {
+      stream_nr = CHUNKID_TO_STREAMNR (tag);
+    
+      if (stream_nr < 0 || stream_nr >= avi->num_streams) {
+        /* recoverable */
+        GST_WARNING ("Invalid stream ID %d (%" GST_FOURCC_FORMAT ")",
+            stream_nr, GST_FOURCC_ARGS (tag));
+    /*    if (!gst_riff_read_skip (riff))
+          return FALSE;*/
+      } else {
+        avi_stream_context *stream;
+        GstClockTime next_ts = 0;
+        GstFormat format;
+        GstBuffer *buf = gst_buffer_new_and_alloc(size);
+        gst_adapter_flush(avi->adapter, 8);
+  
+        /* get buffer */
+        data = gst_adapter_peek(avi->adapter, ((size + 1) & ~1));
+        memcpy( GST_BUFFER_DATA(buf), data, size);
+        GST_BUFFER_SIZE(buf) = size;
+  
+        avi->offset += 8 + ((size + 1) & ~1);
+        gst_adapter_flush(avi->adapter, ((size + 1) & ~1));
+    
+        /* get time of this buffer */
+        stream = &avi->stream[stream_nr];
+        format = GST_FORMAT_TIME;
+        gst_pad_query_position(stream->pad, &format, &next_ts);
+    
+        /* set delay (if any) */
+    //     if (stream->strh->init_frames == stream->current_frame &&
+    //         stream->delay == 0)
+    //       stream->delay = next_ts;
+    
+        stream->current_frame++;
+        stream->current_byte += GST_BUFFER_SIZE (buf);
+    
+        /* should we skip this data? */
+    /*    if (stream->skip) {
+          stream->skip--;
+          gst_buffer_unref (buf);
+        } else {*/
+          if (!stream->pad || ! gst_pad_is_linked (stream->pad)) {
+            gst_buffer_unref (buf);
+          } else {
+            GstClockTime dur_ts = 0;
+    
+            if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
+              buf = gst_avi_demux_invert (stream, buf);
+            }
+    
+            GST_BUFFER_TIMESTAMP (buf) = next_ts;
+            gst_pad_query_position(stream->pad, &format, &dur_ts);
+  
+            GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
+            gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
+            GST_DEBUG_OBJECT (avi,
+                "Pushing buffer with time=%" GST_TIME_FORMAT " over pad %s",
+                GST_TIME_ARGS (next_ts), GST_PAD_NAME (stream->pad));
+            res = gst_pad_push (stream->pad, buf);
+            if ( res == GST_FLOW_OK ) {
+              GST_DEBUG("Push ok!\n");
+            } else {
+              return res;
+            }
+          }
+      } 
+        //}
+    } else {
+      GST_DEBUG("Chunk with size 0. Skip it\n");
+      gst_adapter_flush(avi->adapter, 8);
     }
   }
 
-  return TRUE;
-#endif
+  return res;
+
 }
 
 static void
@@ -2459,13 +2854,80 @@
   }
 }
 
+
+static GstFlowReturn
+gst_avi_demux_chain(GstPad *pad, GstBuffer *buf) {
+
+  GstFlowReturn res = GST_FLOW_OK;
+  GstAviDemux *avi = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
+
+  GST_DEBUG("avi _chain\n");
+
+  gst_adapter_push(avi->adapter, buf);
+
+  switch (avi->state) {
+    case GST_AVI_DEMUX_START:
+      if ((res = gst_avi_demux_parse_stream_init (avi)) != GST_FLOW_OK)
+        goto pause;
+      /* fall-through */
+    case GST_AVI_DEMUX_HEADER:
+      if ((res = gst_avi_demux_parse_stream_header (avi)) != GST_FLOW_OK) {
+        GST_DEBUG("gst flow not ok, going to pause\n");
+        goto pause;
+      }
+      break;
+    case GST_AVI_DEMUX_MOVI:
+      if (avi->seek_event) {
+        gst_avi_demux_send_event (avi, avi->seek_event);
+        avi->seek_event = NULL;
+      }
+      if ((res = gst_avi_demux_stream_data (avi)) != GST_FLOW_OK) {
+        GST_DEBUG("stream_data flow: %s", gst_flow_get_name (res));
+        goto pause;
+      }
+      break;
+    default:
+      g_assert_not_reached ();
+  }
+
+  return res;
+
+pause:
+    GST_DEBUG("Pausing task\n");
+    GST_LOG_OBJECT (avi, "pausing task");
+  gst_pad_pause_task (avi->sinkpad);
+  if (GST_FLOW_IS_FATAL (res)) {
+    guint stream = avi->num_streams;
+
+    /* for fatal errors we post an error message */
+    GST_ELEMENT_ERROR (avi, STREAM, FAILED,
+                       (_("Internal data stream error.")),
+                       ("streaming stopped, reason %s", gst_flow_get_name (res)));
+    while (stream--) {
+      if (avi->stream[stream].pad)
+        gst_pad_push_event (avi->stream[stream].pad, gst_event_new_eos ());
+    }
+  }
+  return res;
+}
+
+
+
 static gboolean
 gst_avi_demux_sink_activate (GstPad * sinkpad)
 {
-  if (gst_pad_check_pull_range (sinkpad))
-    return gst_pad_activate_pull (sinkpad, TRUE);
+  GstAviDemux *avidemux = GST_AVI_DEMUX (gst_pad_get_parent (sinkpad));
 
-  return FALSE;
+  if (gst_pad_check_pull_range (sinkpad)) {
+    avidemux->adapter = NULL;
+    gst_object_unref(avidemux);
+    return gst_pad_activate_pull (sinkpad, TRUE);
+  } else {
+    GST_DEBUG("going to push (streaming) mode\n");
+    avidemux->adapter = gst_adapter_new();
+    gst_object_unref(avidemux);
+    return gst_pad_activate_push (sinkpad, TRUE);
+  }
 }
 
 static gboolean
@@ -2481,6 +2943,20 @@
   return TRUE;
 }
 
+static gboolean
+gst_avi_demux_activate_push(GstPad  *pad, gboolean active)
+{
+
+  if (active) {
+    GST_DEBUG("avi: activating push/chain function");
+  } else {
+    GST_DEBUG("avi: deactivating push/chain function");
+  }
+
+  return TRUE;
+}
+
+
 static GstStateChangeReturn
 gst_avi_demux_change_state (GstElement * element, GstStateChange transition)
 {
@@ -2504,6 +2980,9 @@
   switch (transition) {
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       gst_avi_demux_reset (avi);
+      if ( avi->adapter ) {
+        gst_adapter_clear(avi->adapter);
+      }
       break;
     default:
       break;
