diff -rupN gst-plugins-bad-1.1.3/sys/uvch264/gstuvch264_mjpgdemux.c gst-plugins-bad-1.1.3.new/sys/uvch264/gstuvch264_mjpgdemux.c
--- gst-plugins-bad-1.1.3/sys/uvch264/gstuvch264_mjpgdemux.c	2013-07-28 12:14:54.000000000 -0400
+++ gst-plugins-bad-1.1.3.new/sys/uvch264/gstuvch264_mjpgdemux.c	2013-08-12 09:38:10.347692978 -0400
@@ -456,6 +456,49 @@ _pts_to_timestamp (GstUvcH264MjpgDemux *
   return TRUE;
 }
 
+#include <linux/videodev2.h>
+
+typedef struct _GstV4l2Meta GstV4l2Meta;
+
+struct _GstV4l2Meta {
+  GstMeta meta;
+
+  gpointer mem;
+  struct v4l2_buffer vbuffer;
+};
+
+#define GST_V4L2_META_GET(buf) ((GstV4l2Meta *)gst_buffer_get_meta(buf,g_type_from_name("GstV4l2MetaAPI")))
+
+typedef struct _GstMetaItem GstMetaItem;
+
+struct _GstMetaItem
+{
+  GstMetaItem *next;
+  GstMeta meta;
+};
+
+#define GST_BUFFER_MEM_MAX         16
+
+typedef struct
+{
+  GstBuffer buffer;
+
+  gsize slice_size;
+
+  /* the memory blocks */
+  guint len;
+  GstMemory *mem[GST_BUFFER_MEM_MAX];
+
+  /* memory of the buffer when allocated from 1 chunk */
+  GstMemory *bufmem;
+
+  /* FIXME, make metadata allocation more efficient by using part of the
+   * GstBufferImpl */
+  GstMetaItem *item;
+} GstBufferImpl;
+
+#define GST_BUFFER_MEM_PTR(b,i)    (((GstBufferImpl *)(b))->mem[i])
+
 static GstFlowReturn
 gst_uvc_h264_mjpg_demux_chain (GstPad * pad,
     GstObject * parent, GstBuffer * buf)
@@ -471,41 +514,59 @@ gst_uvc_h264_mjpg_demux_chain (GstPad *
   guint last_offset;
   guint i;
   GstMapInfo info;
+  guint8 *ptr;
+  guint32 size;
+
+  GstV4l2Meta *meta = GST_V4L2_META_GET (buf);
 
   self = GST_UVC_H264_MJPG_DEMUX (GST_PAD_PARENT (pad));
 
+  GST_DEBUG_OBJECT (self, "meta %p, meta->mem %p, meta->vbuffer.bytesused %u", meta, meta->mem, meta->vbuffer.bytesused);
+
   if (gst_buffer_get_size (buf) == 0) {
     return gst_pad_push (self->priv->jpeg_pad, buf);
   }
 
   last_offset = 0;
-  gst_buffer_map (buf, &info, GST_MAP_READ);
+#if 1
+  /*gst_buffer_map (buf, &info, GST_MAP_READ);*/
+  info.memory =  GST_BUFFER_MEM_PTR(buf, 0);
+  ptr = (guint8*)meta->mem/*info.data*/;
+  size = meta->vbuffer.bytesused/*info.size*/;
+#else
+  ptr = (guint8*)meta->mem;
+  size = meta->vbuffer.bytesused;
+#endif
 
   jpeg_buf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_METADATA, 0, 0);
 
-  for (i = 0; i < info.size - 1; i++) {
+  for (i = 0; i < size - 1; i++) {
     /* Check for APP4 (0xe4) marker in the jpeg */
-    if (info.data[i] == 0xff && info.data[i + 1] == 0xe4) {
+    if (ptr[i] == 0xff && ptr[i + 1] == 0xe4) {
       guint16 segment_size;
 
       /* Sanity check sizes and get segment size */
-      if (i + 4 >= info.size) {
+      if (i + 4 >= size) {
         GST_ELEMENT_ERROR (self, STREAM, DEMUX,
             ("Not enough data to read marker size"), (NULL));
         ret = GST_FLOW_ERROR;
         goto done;
       }
-      segment_size = GUINT16_FROM_BE (*((guint16 *) (info.data + i + 2)));
+      segment_size = GUINT16_FROM_BE (*((guint16 *) (ptr + i + 2)));
 
-      if (i + segment_size + 2 >= info.size) {
+      GST_DEBUG_OBJECT (self,
+          "Found APP4 marker (%d). JPG: %d-%d - APP4: %d - %d", segment_size,
+          last_offset, i, i, i + 2 + segment_size);
+
+      if (i + segment_size + 2 >= size) {
         GST_ELEMENT_ERROR (self, STREAM, DEMUX,
             ("Not enough data to read marker content"), (NULL));
         ret = GST_FLOW_ERROR;
         goto done;
       }
-      GST_DEBUG_OBJECT (self,
-          "Found APP4 marker (%d). JPG: %d-%d - APP4: %d - %d", segment_size,
-          last_offset, i, i, i + 2 + segment_size);
+      //GST_DEBUG_OBJECT (self,
+      //    "Found APP4 marker (%d). JPG: %d-%d - APP4: %d - %d", segment_size,
+      //    last_offset, i, i, i + 2 + segment_size);
 
       /* Add JPEG data between the last offset and this market */
       if (i - last_offset > 0) {
@@ -513,6 +574,7 @@ gst_uvc_h264_mjpg_demux_chain (GstPad *
             i - last_offset);
         gst_buffer_append_memory (jpeg_buf, m);
       }
+
       last_offset = i + 2 + segment_size;
 
       /* Reset i/segment size to the app4 data (ignore marker header/size) */
@@ -528,7 +590,7 @@ gst_uvc_h264_mjpg_demux_chain (GstPad *
           goto done;
         }
 
-        aux_header = *((AuxiliaryStreamHeader *) (info.data + i));
+        aux_header = *((AuxiliaryStreamHeader *) (ptr + i));
         /* version should be little endian but it looks more like BE */
         aux_header.version = GUINT16_FROM_BE (aux_header.version);
         aux_header.header_len = GUINT16_FROM_LE (aux_header.header_len);
@@ -543,7 +605,7 @@ gst_uvc_h264_mjpg_demux_chain (GstPad *
             GST_FOURCC_ARGS (aux_header.type),
             aux_header.width, aux_header.height,
             aux_header.frame_interval, aux_header.delay, aux_header.pts);
-        aux_size = *((guint32 *) (info.data + i + aux_header.header_len));
+        aux_size = *((guint32 *) (ptr + i + aux_header.header_len));
         GST_DEBUG_OBJECT (self, "Auxiliary stream size : %d bytes", aux_size);
 
         if (aux_size > 0) {
@@ -663,15 +725,15 @@ gst_uvc_h264_mjpg_demux_chain (GstPad *
       }
 
       i += segment_size - 1;
-    } else if (info.data[i] == 0xff && info.data[i + 1] == 0xda) {
+    } else if (ptr[i] == 0xff && ptr[i + 1] == 0xda) {
       GstMemory *m;
 
       /* The APP4 markers must be before the SOS marker, so this is the end */
       GST_DEBUG_OBJECT (self, "Found SOS marker.");
 
-      m = gst_memory_copy (info.memory, last_offset, info.size - last_offset);
+      m = gst_memory_copy (info.memory, last_offset, size - last_offset);
       gst_buffer_append_memory (jpeg_buf, m);
-      last_offset = info.size;
+      last_offset = size;
       break;
     }
   }
@@ -683,7 +745,7 @@ gst_uvc_h264_mjpg_demux_chain (GstPad *
     goto done;
   }
 
-  if (last_offset != info.size) {
+  if (last_offset != size) {
     /* this means there was no SOS marker in the jpg, so we assume the JPG was
        just a container */
     GST_DEBUG_OBJECT (self, "SOS marker wasn't found. MJPG is container only");
@@ -706,7 +768,7 @@ done:
   if (jpeg_buf)
     gst_buffer_unref (jpeg_buf);
 
-  gst_buffer_unmap (buf, &info);
+  /* gst_buffer_unmap (buf, &info); */
 
   /* We must always unref the input buffer since we never push it out */
   gst_buffer_unref (buf);
