diff --git a/common b/common
index 11f0cd5..69b981f 160000
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 11f0cd5a3fba36f85cf3e434150bfe66b1bf08d4
+Subproject commit 69b981f10caa234ad0ff639179d0fda8505bd94b
diff --git a/gst/audioparsers/gstdcaparse.c b/gst/audioparsers/gstdcaparse.c
index 2c020e7..7f2abaf 100644
--- a/gst/audioparsers/gstdcaparse.c
+++ b/gst/audioparsers/gstdcaparse.c
@@ -92,7 +92,7 @@ gst_dca_parse_base_init (gpointer klass)
       gst_static_pad_template_get (&src_template));
 
   gst_element_class_set_details_simple (element_class,
-      "DTS Coherent Acoustics audio stream parser", "Codec/Parser/Audio",
+      "DTS Coherent Acoustics audio stream parser", "Codec/Parser/Converter/Audio",
       "DCA parser", "Tim-Philipp Müller <tim centricular net>");
 }
 
@@ -120,7 +120,9 @@ gst_dca_parse_reset (GstDcaParse * dcaparse)
   dcaparse->channels = -1;
   dcaparse->rate = -1;
   dcaparse->depth = -1;
+  dcaparse->depth_negotiated = -1;
   dcaparse->endianness = -1;
+  dcaparse->endianness_negotiated = -1;
   dcaparse->block_size = -1;
   dcaparse->frame_size = -1;
   dcaparse->last_sync = 0;
@@ -160,6 +162,40 @@ gst_dca_parse_stop (GstBaseParse * parse)
   return TRUE;
 }
 
+static void
+gst_dca_parse_negotiate (GstDcaParse * dcaparse)
+{
+  GstCaps *caps;
+
+  caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (dcaparse));
+  GST_DEBUG_OBJECT (dcaparse, "***gst_dca_parse_negotiate*** allowed caps: %" GST_PTR_FORMAT, caps);
+
+  if (caps && gst_caps_get_size (caps) > 0) {
+    GstStructure *s = gst_caps_get_structure (caps, 0);
+    gint depth, endianness;
+
+    if (gst_structure_get_int (s, "depth", &depth)) {
+      dcaparse->depth_negotiated = depth; 
+      GST_DEBUG_OBJECT (dcaparse, "downstream depth negotiated to %i (native = %i)", depth, dcaparse->depth);
+    }
+    else {
+      dcaparse->depth_negotiated = dcaparse->depth;
+      GST_DEBUG_OBJECT (dcaparse, "downstream depth not negotiated, stays native %i", dcaparse->depth);
+    }
+    
+    if (gst_structure_get_int (s, "endianness", &endianness)) {
+      dcaparse->endianness_negotiated = endianness; 
+      GST_DEBUG_OBJECT (dcaparse, "downstream endianness negotiated to %i (native = %i)", endianness, dcaparse->endianness);
+    }
+    else {
+      GST_DEBUG_OBJECT (dcaparse, "downstream endianness not negotiated, stays native %i", dcaparse->endianness);
+      dcaparse->endianness_negotiated = dcaparse->endianness;
+    }
+  }
+  if (caps)
+    gst_caps_unref (caps);
+}
+
 static gboolean
 gst_dca_parse_parse_header (GstDcaParse * dcaparse,
     const GstByteReader * reader, guint * frame_size,
@@ -403,6 +439,7 @@ gst_dca_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
 {
   GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
   GstBuffer *buf = frame->buffer;
+  unsigned char *data;
   GstByteReader r = GST_BYTE_READER_INIT_FROM_BUFFER (buf);
   guint size, rate, chans, depth, block_size, num_blocks, samples_per_block;
   gint endianness;
@@ -412,6 +449,73 @@ gst_dca_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
           &endianness, &num_blocks, &samples_per_block, &terminator))
     goto broken_header;
 
+  if (G_UNLIKELY (dcaparse->endianness_negotiated < 0 || dcaparse->depth_negotiated < 0)) {
+      dcaparse->depth = depth;
+      dcaparse->endianness = endianness;
+      gst_dca_parse_negotiate(dcaparse);
+    }
+
+  data = GST_BUFFER_DATA(buf);
+
+  if (endianness != dcaparse->endianness_negotiated )
+  {
+    guint16 tmp;
+    guint pos = 0;
+    GST_INFO_OBJECT (parse, "stream endianness is %i, downstream negotiated %i -> requires byteswap", endianness, dcaparse->endianness_negotiated);
+    if (endianness == G_LITTLE_ENDIAN) {
+      		  for (pos = 0; pos < size - 2; pos += 2) {   
+		      tmp = GST_READ_UINT16_LE (data + pos);
+		  GST_WRITE_UINT16_BE (data + pos, tmp);
+		  }
+		  endianness = G_BIG_ENDIAN;
+    }
+    else {
+      		  for (pos = 0; pos < size - 2; pos += 2) {   
+		      tmp = GST_READ_UINT16_BE (data + pos);
+		  GST_WRITE_UINT16_LE (data + pos, tmp);
+		  }
+		  endianness = G_LITTLE_ENDIAN;
+    }
+  }
+  
+  if (depth == 14 && dcaparse->depth_negotiated == 16)
+  {
+
+		    guint pos14 = 0;
+		    guint pos16 = 0;
+    GST_INFO_OBJECT (parse, "stream depth is 14 bit, downstream negotiated 16 bit -> requires upconversion");
+		    while (pos16 <= size-14) { 
+		      GST_WRITE_UINT16_BE(data+pos16, ((GST_READ_UINT16_BE(data+pos14) << 2) | ((GST_READ_UINT16_BE(data+pos14+2) >> 12) & 0x0003)));
+		      pos14 += 2;
+		      pos16 += 2;
+		      
+		      GST_WRITE_UINT16_BE(data+pos16, ((GST_READ_UINT16_BE(data+pos14) << 4) | ((GST_READ_UINT16_BE(data+pos14+2) >> 10) & 0x000F)));      
+		      pos14 += 2;
+		      pos16 += 2;
+		      
+		      GST_WRITE_UINT16_BE(data+pos16, ((GST_READ_UINT16_BE(data+pos14) << 6) | ((GST_READ_UINT16_BE(data+pos14+2) >> 8) & 0x003F)));
+		      pos14 += 2;
+		      pos16 += 2;
+
+		      GST_WRITE_UINT16_BE(data+pos16, ((GST_READ_UINT16_BE(data+pos14) << 8) | ((GST_READ_UINT16_BE(data+pos14+2) >> 6) & 0x00FF)));
+		      pos14 += 2;
+		      pos16 += 2;
+
+		      GST_WRITE_UINT16_BE(data+pos16, ((GST_READ_UINT16_BE(data+pos14) << 10) | ((GST_READ_UINT16_BE(data+pos14+2) >> 4) & 0x03FF)));
+		      pos14 += 2;
+		      pos16 += 2;
+
+		      GST_WRITE_UINT16_BE(data+pos16, ((GST_READ_UINT16_BE(data+pos14) << 12) | ((GST_READ_UINT16_BE(data+pos14+2) >> 2) & 0x0FFF)));
+		      pos14 += 2;
+		      pos16 += 2;
+
+		      GST_WRITE_UINT16_BE(data+pos16, ((GST_READ_UINT16_BE(data+pos14) << 14) | ((GST_READ_UINT16_BE(data+pos14+2) >> 0) & 0x3FFF)));
+		      pos14 += 4;
+		      pos16 += 2;
+		    }
+		    depth = 16;
+  }  
+  
   block_size = num_blocks * samples_per_block;
 
   if (G_UNLIKELY (dcaparse->rate != rate || dcaparse->channels != chans
diff --git a/gst/audioparsers/gstdcaparse.h b/gst/audioparsers/gstdcaparse.h
index b3e066b..f59a7f2 100644
--- a/gst/audioparsers/gstdcaparse.h
+++ b/gst/audioparsers/gstdcaparse.h
@@ -54,7 +54,9 @@ struct _GstDcaParse {
   gint         rate;
   gint         channels;
   gint         depth;
+  gint         depth_negotiated;
   gint         endianness;
+  gint         endianness_negotiated;
   gint         block_size;
   gint         frame_size;
 
