diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
index 521c4a6..931f1c8 100644
--- a/ext/pulse/pulsesink.c
+++ b/ext/pulse/pulsesink.c
@@ -2022,6 +2022,13 @@ gst_pulsesink_get_time (GstClock * clock, GstAudioBaseSink * sink)
   }
 
   pa_threaded_mainloop_lock (mainloop);
+
+  /* Need to check if pa stream is valid as it may be released by caps change*/
+  if (!pbuf->stream) {
+    pa_threaded_mainloop_unlock (mainloop);
+    return GST_CLOCK_TIME_NONE;
+  }
+
   if (gst_pulsering_is_dead (psink, pbuf, TRUE))
     goto server_dead;
 
diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c
index c9ce304..e2c2bc9 100644
--- a/gst/audioparsers/gstaacparse.c
+++ b/gst/audioparsers/gstaacparse.c
@@ -85,6 +85,35 @@ static const gint loas_channels_table[16] = {
   0, 0, 0, 7, 8, 0, 8, 0
 };
 
+typedef struct
+{
+  guint32 num_ele;
+  guint32 ele_is_cpe[16];
+  guint32 ele_tag[16];
+} GstAacEleList;
+
+typedef struct
+{
+  guint32 present;
+  guint32 ele_tag;
+  guint32 pseudo_enab;
+} GstAacMIXdown;
+
+typedef struct
+{
+  guint32 profile;
+  guint32 sr_idx;
+  GstAacEleList front;
+  GstAacEleList side;
+  GstAacEleList back;
+  GstAacEleList data;
+  GstAacEleList lfe;
+  GstAacEleList coupling;
+  GstAacMIXdown mono_mix;
+  GstAacMIXdown stereo_mix;
+  GstAacMIXdown matrix_mix;
+} GstAacProgConfig;
+
 static gboolean gst_aac_parse_start (GstBaseParse * parse);
 static gboolean gst_aac_parse_stop (GstBaseParse * parse);
 
@@ -104,6 +133,9 @@ static gboolean gst_aac_parse_read_audio_specific_config (GstAacParse *
     aacparse, GstBitReader * br, gint * object_type, gint * sample_rate,
     gint * channels, gint * frame_samples);
 
+static gboolean gst_aac_parse_read_program_config_element (GstAacProgConfig *
+    progConfig, GstBitReader * br);
+
 
 #define gst_aac_parse_parent_class parent_class
 G_DEFINE_TYPE (GstAacParse, gst_aac_parse, GST_TYPE_BASE_PARSE);
@@ -844,6 +876,87 @@ gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
     *object = ((data[2] & 0xc0) >> 6) + 1;
 }
 
+static void
+gst_aac_parse_get_ele_list (GstAacEleList * pList, gint32 cpe,
+    GstBitReader * br)
+{
+  guint32 count, num_elem;
+  num_elem = pList->num_ele;
+  for (count = 0; count < num_elem; count++) {
+    if (cpe) {
+      gst_bit_reader_get_bits_uint32 (br, &(pList->ele_is_cpe[count]), 1);
+    } else {
+      pList->ele_is_cpe[count] = 0;
+    }
+    gst_bit_reader_get_bits_uint32 (br, &(pList->ele_tag[count]), 4);
+  }
+}
+
+static gint32
+gst_aac_parse_get_config_channels (GstAacEleList * pList)
+{
+  guint32 count, num_elem, channels = 0;
+  num_elem = pList->num_ele;
+  for (count = 0; count < num_elem; count++) {
+    channels++;
+    if (pList->ele_is_cpe[count] == 1) {
+      /* CPE element channels++ */
+      channels++;
+    }
+  }
+  return channels;
+}
+
+/* Read program config element
+ISO/IEC 14496-3, 4.4.1.1  read program config element */
+static gboolean
+gst_aac_parse_read_program_config_element (GstAacProgConfig *
+    progConfig, GstBitReader * br)
+{
+  guint32 count = 0;
+  guint32 bytes = 0;
+
+  gst_bit_reader_skip (br, 4);  //element_instance_tag
+
+  gst_bit_reader_get_bits_uint32 (br, &progConfig->profile, 2);
+  gst_bit_reader_get_bits_uint32 (br, &progConfig->sr_idx, 4);
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->front.num_ele), 4);
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->side.num_ele), 4);
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->back.num_ele), 4);
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->lfe.num_ele), 2);
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->data.num_ele), 3);
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->coupling.num_ele), 4);
+
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->mono_mix.present), 1);
+  if (progConfig->mono_mix.present) {
+    gst_bit_reader_get_bits_uint32 (br, &(progConfig->mono_mix.ele_tag), 4);
+  }
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->stereo_mix.present), 1);
+  if (progConfig->mono_mix.present) {
+    gst_bit_reader_get_bits_uint32 (br, &(progConfig->stereo_mix.ele_tag), 4);
+  }
+  gst_bit_reader_get_bits_uint32 (br, &(progConfig->matrix_mix.present), 1);
+  if (progConfig->mono_mix.present) {
+    gst_bit_reader_get_bits_uint32 (br, &(progConfig->matrix_mix.ele_tag), 2);
+    gst_bit_reader_get_bits_uint32 (br, &(progConfig->matrix_mix.pseudo_enab), 1);
+  }
+
+  gst_aac_parse_get_ele_list (&progConfig->front, 1, br);
+  gst_aac_parse_get_ele_list (&progConfig->side, 1, br);
+  gst_aac_parse_get_ele_list (&progConfig->back, 1, br);
+  gst_aac_parse_get_ele_list (&progConfig->data, 0, br);
+  gst_aac_parse_get_ele_list (&progConfig->lfe, 0, br);
+  gst_aac_parse_get_ele_list (&progConfig->coupling, 1, br);
+
+  gst_bit_reader_skip_to_byte (br);     // byte_alignment
+
+  gst_bit_reader_get_bits_uint32 (br, &bytes, 8);       //comment_field_bytes
+  for (count = 0; count < bytes; count++) {
+    gst_bit_reader_skip (br, 8);        //skip comment data
+  }
+  return TRUE;
+}
+
 /**
  * gst_aac_parse_detect_stream:
  * @aacparse: #GstAacParse.
@@ -915,7 +1028,7 @@ gst_aac_parse_detect_stream (GstAacParse * aacparse,
     gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
         &aacparse->object_type, &aacparse->mpegversion);
 
-    if (!channels || !framesize) {
+    if (!framesize) {
       GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
       return FALSE;
     }
@@ -973,68 +1086,56 @@ gst_aac_parse_detect_stream (GstAacParse * aacparse,
     return FALSE;
 
   if (memcmp (data + i, "ADIF", 4) == 0) {
-    const guint8 *adif;
-    int skip_size = 0;
-    int bitstream_type;
+    GstBitReader br;
+    guint8 u8 = 0;
+    guint8 bitstream_type = 0;
+    guint num_elems = 0;
+    guint bitrate = 0;
+    guint count;
     int sr_idx;
     GstCaps *sinkcaps;
-
+    GstAacProgConfig *progConfig;
     aacparse->header_type = DSPAAC_HEADER_ADIF;
     aacparse->mpegversion = 4;
-
-    /* Skip the "ADIF" bytes */
-    adif = data + i + 4;
-
-    /* copyright string */
-    if (adif[0] & 0x80)
-      skip_size += 9;           /* skip 9 bytes */
-
-    bitstream_type = adif[0 + skip_size] & 0x10;
-    aacparse->bitrate =
-        ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
-        ((unsigned int) adif[1 + skip_size] << 11) |
-        ((unsigned int) adif[2 + skip_size] << 3) |
-        ((unsigned int) adif[3 + skip_size] & 0xe0);
-
-    /* CBR */
+    gst_bit_reader_init (&br, data + i, avail - i);
+    /* skip sync word (adif 4 byte ) */
+    gst_bit_reader_skip (&br, 32);
+    gst_bit_reader_get_bits_uint8 (&br, &u8, 1);
+    if (u8) {
+      gst_bit_reader_skip (&br, 72);    //copyright_id
+    }
+    gst_bit_reader_skip (&br, 2);       // original_copy and home
+    gst_bit_reader_get_bits_uint8 (&br, &bitstream_type, 1);
+    gst_bit_reader_get_bits_uint32 (&br, &bitrate, 23);
+    gst_bit_reader_get_bits_uint32 (&br, &num_elems, 4);
     if (bitstream_type == 0) {
-#if 0
-      /* Buffer fullness parsing. Currently not needed... */
-      guint num_elems = 0;
-      guint fullness = 0;
-
-      num_elems = (adif[3 + skip_size] & 0x1e);
-      GST_INFO ("ADIF num_config_elems: %d", num_elems);
-
-      fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
-          ((unsigned int) adif[4 + skip_size] << 11) |
-          ((unsigned int) adif[5 + skip_size] << 3) |
-          ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
-
-      GST_INFO ("ADIF buffer fullness: %d", fullness);
-#endif
-      aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
-          ((adif[7 + skip_size] & 0x80) >> 7);
-      sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
+      gst_bit_reader_skip (&br, 20);    //adif_buffer_fullness
     }
-    /* VBR */
-    else {
-      aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
-      sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
-          ((adif[5 + skip_size] & 0x80) >> 7);
+
+    progConfig =
+        (GstAacProgConfig *) g_malloc0 ((num_elems+1) * sizeof (GstAacProgConfig));
+    for ( count = 0; count < num_elems + 1; count++) {
+      gst_aac_parse_read_program_config_element (&progConfig[count], &br);
+      aacparse->channels +=
+          gst_aac_parse_get_config_channels (&(progConfig[count].front));
+      aacparse->channels +=
+          gst_aac_parse_get_config_channels (&(progConfig[count].side));
+      aacparse->channels +=
+          gst_aac_parse_get_config_channels (&(progConfig[count].back));
+      aacparse->channels +=
+          gst_aac_parse_get_config_channels (&(progConfig[count].lfe));
+      aacparse->channels +=
+          gst_aac_parse_get_config_channels (&(progConfig[count].coupling));
     }
 
-    /* FIXME: This gives totally wrong results. Duration calculation cannot
-       be based on this */
+    aacparse->bitrate = (gint)bitrate;
+    aacparse->object_type = progConfig[0].profile + 1;
+    sr_idx = progConfig[0].sr_idx;
+    g_free(progConfig);
+
     aacparse->sample_rate =
         gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
 
-    /* baseparse is not given any fps,
-     * so it will give up on timestamps, seeking, etc */
-
-    /* FIXME: Can we assume this? */
-    aacparse->channels = 2;
-
     GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
         aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
 
diff --git a/gst/rtp/gstrtpmp4gpay.c b/gst/rtp/gstrtpmp4gpay.c
index 7333b49..35f2c8c 100644
--- a/gst/rtp/gstrtpmp4gpay.c
+++ b/gst/rtp/gstrtpmp4gpay.c
@@ -390,6 +390,7 @@ gst_rtp_mp4g_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
   const GValue *codec_data;
   const gchar *media_type = NULL;
   gboolean res;
+  const gchar *name;
 
   rtpmp4gpay = GST_RTP_MP4G_PAY (payload);
 
@@ -400,7 +401,6 @@ gst_rtp_mp4g_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
     GST_LOG_OBJECT (rtpmp4gpay, "got codec_data");
     if (G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) {
       GstBuffer *buffer;
-      const gchar *name;
 
       buffer = gst_value_get_buffer (codec_data);
       GST_LOG_OBJECT (rtpmp4gpay, "configuring codec_data");
@@ -426,6 +426,23 @@ gst_rtp_mp4g_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
 
       rtpmp4gpay->config = gst_buffer_copy (buffer);
     }
+  } else {
+    name = gst_structure_get_name (structure);
+
+    if (!strcmp (name, "video/mpeg")) {
+      rtpmp4gpay->profile = g_strdup ("1");
+
+      /* fixed rate */
+      rtpmp4gpay->rate = 90000;
+      /* video stream type */
+      rtpmp4gpay->streamtype = "4";
+      /* no params for video */
+      rtpmp4gpay->params = NULL;
+      /* mode */
+      rtpmp4gpay->mode = "generic";
+
+      media_type = "video";
+    }
   }
   if (media_type == NULL)
     goto config_failed;
diff --git a/sys/v4l2/gstv4l2allocator.c b/sys/v4l2/gstv4l2allocator.c
index 2047383..ecab01e 100644
--- a/sys/v4l2/gstv4l2allocator.c
+++ b/sys/v4l2/gstv4l2allocator.c
@@ -818,7 +818,7 @@ gst_v4l2_allocator_alloc_mmap (GstV4l2Allocator * allocator)
           "mmap buffer length %d, data offset %d, plane %d",
           group->planes[i].length, group->planes[i].data_offset, i);
 
-      group->mem[i] = (GstMemory *) _v4l2mem_new (0, GST_ALLOCATOR (allocator),
+      group->mem[i] = (GstMemory *) _v4l2mem_new (GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, GST_ALLOCATOR (allocator),
           NULL, group->planes[i].length, 0, 0, group->planes[i].length, i,
           data, -1, group);
     } else {
@@ -879,7 +879,7 @@ gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
       GST_LOG_OBJECT (allocator, "exported DMABUF as fd %i plane %d",
           expbuf.fd, i);
 
-      group->mem[i] = (GstMemory *) _v4l2mem_new (0, GST_ALLOCATOR (allocator),
+      group->mem[i] = (GstMemory *) _v4l2mem_new (GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, GST_ALLOCATOR (allocator),
           NULL, group->planes[i].length, 0, 0, group->planes[i].length, i,
           NULL, expbuf.fd, group);
     } else {
