gst/rtp/: Update theora pay/depayloader in a similar to vorbis.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 14 May 2007 17:10:12 +0000 (17:10 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 14 May 2007 17:10:12 +0000 (17:10 +0000)
Original commit message from CVS:
* gst/rtp/gstrtptheoradepay.c: (decode_base64),
(gst_rtp_theora_depay_parse_configuration):
* gst/rtp/gstrtptheorapay.c: (encode_base64),
(gst_rtp_theora_pay_finish_headers),
(gst_rtp_theora_pay_handle_buffer):
Update theora pay/depayloader in a similar to vorbis.
* gst/rtp/gstrtpvorbisdepay.c:
(gst_rtp_vorbis_depay_parse_configuration):
Update docs.

ChangeLog
gst/rtp/gstrtptheoradepay.c
gst/rtp/gstrtptheorapay.c
gst/rtp/gstrtpvorbisdepay.c

index e65740a..955958c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2007-05-14  Wim Taymans  <wim@fluendo.com>
 
+       * gst/rtp/gstrtptheoradepay.c: (decode_base64),
+       (gst_rtp_theora_depay_parse_configuration):
+       * gst/rtp/gstrtptheorapay.c: (encode_base64),
+       (gst_rtp_theora_pay_finish_headers),
+       (gst_rtp_theora_pay_handle_buffer):
+       Update theora pay/depayloader in a similar to vorbis.
+
+       * gst/rtp/gstrtpvorbisdepay.c:
+       (gst_rtp_vorbis_depay_parse_configuration):
+       Update docs.
+
+2007-05-14  Wim Taymans  <wim@fluendo.com>
+
        * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_send):
        When we try to execute a method that is not supported by the server,
        don't error out but remove the method from the accepted methods so that
index 47ab382..a8a642e 100644 (file)
@@ -59,7 +59,9 @@ GST_STATIC_PAD_TEMPLATE ("sink",
         "clock-rate = (int) [1, MAX ], " "encoding-name = (string) \"THEORA\""
         /* All required parameters 
          *
-         * "encoding-params = (string) <num channels>"
+         * "sampling = (string) { "YCbCr-4:2:0", "YCbCr-4:2:2", "YCbCr-4:4:4" } "
+         * "width = (string) [1, 1048561] (multiples of 16) "
+         * "height = (string) [1, 1048561] (multiples of 16) "
          * "delivery-method = (string) { inline, in_band, out_band/<specific_name> } " 
          * "configuration = (string) ANY" 
          */
@@ -77,9 +79,6 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("video/x-theora")
     );
 
-/* 42 bytes for the theora identification packet length */
-#define THEORA_ID_LEN  42
-
 GST_BOILERPLATE (GstRtpTheoraDepay, gst_rtp_theora_depay, GstBaseRTPDepayload,
     GST_TYPE_BASE_RTP_DEPAYLOAD);
 
@@ -151,28 +150,70 @@ gst_rtp_theora_depay_finalize (GObject * object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static const guint8 a2bin[256] = {
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
+  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
+  64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
+  64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+};
+
+static guint
+decode_base64 (const gchar * in, guint8 * out)
+{
+  guint8 v1, v2;
+  guint len = 0;
+
+  v1 = a2bin[(gint) * in];
+  while (v1 <= 63) {
+    /* read 4 bytes, write 3 bytes, invalid base64 are zeroes */
+    v2 = a2bin[(gint) * ++in];
+    *out++ = (v1 << 2) | ((v2 & 0x3f) >> 4);
+    v1 = (v2 > 63 ? 64 : a2bin[(gint) * ++in]);
+    *out++ = (v2 << 4) | ((v1 & 0x3f) >> 2);
+    v2 = (v1 > 63 ? 64 : a2bin[(gint) * ++in]);
+    *out++ = (v1 << 6) | (v2 & 0x3f);
+    v1 = (v2 > 63 ? 64 : a2bin[(gint) * ++in]);
+    len += 3;
+  }
+  /* move to '\0' */
+  while (*in != '\0')
+    in++;
+
+  /* subtract padding */
+  while (len > 0 && *--in == '=')
+    len--;
+
+  return len;
+}
+
 static gboolean
 gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay,
     const gchar * configuration)
 {
-  GValue v = { 0 };
   GstBuffer *buf;
   guint32 num_headers;
   guint8 *data;
   guint size;
-  gint i;
-
-  /* deserialize base16 to buffer */
-  g_value_init (&v, GST_TYPE_BUFFER);
-  if (!gst_value_deserialize (&v, configuration))
-    goto wrong_configuration;
+  gint i, j;
 
-  buf = gst_value_get_buffer (&v);
-  gst_buffer_ref (buf);
-  g_value_unset (&v);
+  /* deserialize base64 to buffer */
+  size = strlen (configuration);
+  GST_DEBUG_OBJECT (rtptheoradepay, "base64 config size %u", size);
 
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
+  data = g_malloc (size);
+  size = decode_base64 (configuration, data);
 
   GST_DEBUG_OBJECT (rtptheoradepay, "config size %u", size);
 
@@ -201,74 +242,96 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay,
   /*  0                   1                   2                   3
    *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |                   Ident                       |              ..
+   * |                   Ident                       | length       ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..              | n. of headers |    length1    |    length2   ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..              |             Identification Header            ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * .................................................................
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * ..   length     |              Identification Header           ..
+   * ..              |         Comment Header                       ..
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * ..                    Identification Header                     |
+   * .................................................................
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..                        Comment Header                        |
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * |                          Setup Header                        ..
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * .................................................................
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * ..                         Setup Header                         |
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   *
    */
   for (i = 0; i < num_headers; i++) {
     guint32 ident;
     guint16 length;
+    guint8 n_headers, b;
     GstRtpTheoraConfig *conf;
-    GstTagList *list;
+    guint *h_sizes;
 
-    if (size < 5)
+    if (size < 6)
       goto too_small;
 
     ident = (data[0] << 16) | (data[1] << 8) | data[2];
     length = (data[3] << 8) | data[4];
-    size -= 5;
-    data += 5;
+    n_headers = data[5];
+    size -= 6;
+    data += 6;
 
-    GST_DEBUG_OBJECT (rtptheoradepay, "header %d, ident %08x, length %u", i,
-        ident, length);
+    GST_DEBUG_OBJECT (rtptheoradepay,
+        "header %d, ident 0x%08x, length %u, left %u", i, ident, length, size);
 
-    if (size < length + THEORA_ID_LEN)
+    if (size < length)
       goto too_small;
 
-    GST_DEBUG_OBJECT (rtptheoradepay, "preparing headers");
+    /* read header sizes we read 2 sizes, the third size (for which we allocate
+     * space) must be derived from the total packed header length. */
+    h_sizes = g_newa (guint, n_headers + 1);
+    for (j = 0; j < n_headers; j++) {
+      guint h_size;
+
+      h_size = 0;
+      do {
+        if (size < 1)
+          goto too_small;
+        b = *data++;
+        size--;
+        h_size = (h_size << 7) | (b & 0x7f);
+      } while (b & 0x80);
+      GST_DEBUG_OBJECT (rtptheoradepay, "headers %d: size: %u", j, h_size);
+      h_sizes[j] = h_size;
+      length -= h_size;
+    }
+    /* last header length is the remaining space */
+    GST_DEBUG_OBJECT (rtptheoradepay, "last header size: %u", length);
+    h_sizes[j] = length;
 
+    GST_DEBUG_OBJECT (rtptheoradepay, "preparing headers");
     conf = g_new0 (GstRtpTheoraConfig, 1);
     conf->ident = ident;
 
-    buf = gst_buffer_new_and_alloc (THEORA_ID_LEN);
-    memcpy (GST_BUFFER_DATA (buf), data, THEORA_ID_LEN);
-    conf->headers = g_list_append (conf->headers, buf);
-    data += THEORA_ID_LEN;
-    size -= THEORA_ID_LEN;
-
-    /* create a dummy comment */
-    list = gst_tag_list_new ();
-    buf =
-        gst_tag_list_to_vorbiscomment_buffer (list, (guint8 *) "\201theora", 7,
-        "Theora RTP depayloader");
-    conf->headers = g_list_append (conf->headers, buf);
-    gst_tag_list_free (list);
-
-    buf = gst_buffer_new_and_alloc (length);
-    memcpy (GST_BUFFER_DATA (buf), data, length);
-    conf->headers = g_list_append (conf->headers, buf);
-    data += length;
-    size -= length;
+    for (j = 0; j <= n_headers; j++) {
+      guint h_size;
+
+      h_size = h_sizes[j];
+      if (size < h_size)
+        goto too_small;
 
+      GST_DEBUG_OBJECT (rtptheoradepay, "reading header %d, size %u", j,
+          h_size);
+
+      buf = gst_buffer_new_and_alloc (h_size);
+      memcpy (GST_BUFFER_DATA (buf), data, h_size);
+      conf->headers = g_list_append (conf->headers, buf);
+      data += h_size;
+      size -= h_size;
+    }
     rtptheoradepay->configs = g_list_append (rtptheoradepay->configs, conf);
   }
-
   return TRUE;
 
   /* ERRORS */
-wrong_configuration:
-  {
-    GST_DEBUG_OBJECT (rtptheoradepay, "error parsing configuration");
-    return FALSE;
-  }
 too_small:
   {
     GST_DEBUG_OBJECT (rtptheoradepay, "configuration too small");
index 418b9f0..c8f907e 100644 (file)
@@ -212,31 +212,46 @@ gst_rtp_theora_pay_flush_packet (GstRtpTheoraPay * rtptheorapay)
   return ret;
 }
 
+static gchar *
+encode_base64 (const guint8 * in, guint size, guint * len)
+{
+  gchar *ret, *d;
+  static const gchar *v =
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+  *len = ((size + 2) / 3) * 4;
+  d = ret = (gchar *) g_malloc (*len + 1);
+  for (; size; in += 3) {       /* process tuplets */
+    *d++ = v[in[0] >> 2];       /* byte 1: high 6 bits (1) */
+    /* byte 2: low 2 bits (1), high 4 bits (2) */
+    *d++ = v[((in[0] << 4) + (--size ? (in[1] >> 4) : 0)) & 0x3f];
+    /* byte 3: low 4 bits (2), high 2 bits (3) */
+    *d++ = size ? v[((in[1] << 2) + (--size ? (in[2] >> 6) : 0)) & 0x3f] : '=';
+    /* byte 4: low 6 bits (3) */
+    *d++ = size ? v[in[2] & 0x3f] : '=';
+    if (size)
+      size--;                   /* count third character if processed */
+  }
+  *d = '\0';                    /* tie off string */
+
+  return ret;                   /* return the resulting string */
+}
+
 static gboolean
 gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
 {
   GstRtpTheoraPay *rtptheorapay = GST_RTP_THEORA_PAY (basepayload);
   GList *walk;
-  guint length;
-  gchar *configuration;
-  gchar *wstr, *hstr;
-  guint8 *data;
+  guint length, size, n_headers, configlen;
+  gchar *wstr, *hstr, *configuration;
+  guint8 *data, *config;
   guint32 ident;
-  GValue v = { 0 };
-  GstBuffer *config;
 
   GST_DEBUG_OBJECT (rtptheorapay, "finish headers");
 
   if (!rtptheorapay->headers)
     goto no_headers;
 
-  /* we need exactly 2 header packets */
-  if (g_list_length (rtptheorapay->headers) != 2) {
-    GST_DEBUG_OBJECT (rtptheorapay, "We need 2 headers but have %d",
-        g_list_length (rtptheorapay->headers));
-    goto no_headers;
-  }
-
   /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * |                     Number of packed headers                  |
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -255,35 +270,60 @@ gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
    *  0                   1                   2                   3
    *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |                   Ident                       |              ..
+   * |                   Ident                       | length       ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..              | n. of headers |    length1    |    length2   ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..              |             Identification Header            ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * .................................................................
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..              |         Comment Header                       ..
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * ..   length     |              Identification Header           ..
+   * .................................................................
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * ..                    Identification Header                     |
+   * ..                        Comment Header                        |
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * |                          Setup Header                        ..
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * .................................................................
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * ..                         Setup Header                         |
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   *
    */
 
-  /* count the size of the headers first */
+  /* we need 4 bytes for the number of headers (which is always 1), 3 bytes for
+   * the ident, 2 bytes for length, 1 byte for n. of headers. */
+  size = 4 + 3 + 2 + 1;
+
+  /* count the size of the headers first and update the hash */
   length = 0;
+  n_headers = 0;
   ident = fnv1_hash_32_new ();
   for (walk = rtptheorapay->headers; walk; walk = g_list_next (walk)) {
     GstBuffer *buf = GST_BUFFER_CAST (walk->data);
-
-    ident =
-        fnv1_hash_32_update (ident, GST_BUFFER_DATA (buf),
+    guint bsize;
+
+    bsize = GST_BUFFER_SIZE (buf);
+    length += bsize;
+    n_headers++;
+
+    /* count number of bytes needed for length fields, we don't need this for
+     * the last header. */
+    if (g_list_next (walk)) {
+      do {
+        size++;
+        bsize >>= 7;
+      } while (bsize);
+    }
+    /* update hash */
+    ident = fnv1_hash_32_update (ident, GST_BUFFER_DATA (buf),
         GST_BUFFER_SIZE (buf));
-    length += GST_BUFFER_SIZE (buf);
   }
 
-  /* total config length is 4 bytes header number + size of the
-   *  headers + 2 bytes length + 3 bytes for the ident */
-  config = gst_buffer_new_and_alloc (length + 4 + 2 + 3);
-  data = GST_BUFFER_DATA (config);
+  /* packet length is header size + packet length */
+  configlen = size + length;
+  config = data = g_malloc (configlen);
 
   /* number of packed headers, we only pack 1 header */
   data[0] = 0;
@@ -293,18 +333,51 @@ gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
 
   ident = fnv1_hash_32_to_24 (ident);
   rtptheorapay->payload_ident = ident;
+  GST_DEBUG_OBJECT (rtptheorapay, "ident 0x%08x", ident);
 
   /* take lower 3 bytes */
   data[4] = (ident >> 16) & 0xff;
   data[5] = (ident >> 8) & 0xff;
   data[6] = ident & 0xff;
 
-  /* store length minus the length of the fixed theora header */
-  data[7] = ((length - THEORA_ID_LEN) >> 8) & 0xff;
-  data[8] = (length - THEORA_ID_LEN) & 0xff;
+  /* store length of all theora headers */
+  data[7] = ((length) >> 8) & 0xff;
+  data[8] = (length) & 0xff;
+
+  /* store number of headers minus one. */
+  data[9] = n_headers - 1;
+  data += 10;
+
+  /* store length for each header */
+  for (walk = rtptheorapay->headers; walk; walk = g_list_next (walk)) {
+    GstBuffer *buf = GST_BUFFER_CAST (walk->data);
+    guint bsize, size, temp;
+
+    /* only need to store the length when it's not the last header */
+    if (!g_list_next (walk))
+      break;
+
+    bsize = GST_BUFFER_SIZE (buf);
+
+    /* calc size */
+    size = 0;
+    do {
+      size++;
+      bsize >>= 7;
+    } while (bsize);
+    temp = size;
+
+    bsize = GST_BUFFER_SIZE (buf);
+    /* write the size backwards */
+    while (size) {
+      size--;
+      data[size] = bsize & 0x7f;
+      bsize >>= 7;
+    }
+    data += temp;
+  }
 
   /* copy header data */
-  data += 9;
   for (walk = rtptheorapay->headers; walk; walk = g_list_next (walk)) {
     GstBuffer *buf = GST_BUFFER_CAST (walk->data);
 
@@ -312,10 +385,9 @@ gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
     data += GST_BUFFER_SIZE (buf);
   }
 
-  /* serialize buffer to base16 */
-  g_value_init (&v, GST_TYPE_BUFFER);
-  gst_value_take_buffer (&v, config);
-  configuration = gst_value_serialize (&v);
+  /* serialize to base64 */
+  configuration = encode_base64 (config, configlen, &size);
+  g_free (config);
 
   /* configure payloader settings */
   wstr = g_strdup_printf ("%d", rtptheorapay->width);
@@ -333,7 +405,6 @@ gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
   g_free (wstr);
   g_free (hstr);
   g_free (configuration);
-  g_value_unset (&v);
 
   return TRUE;
 
@@ -454,12 +525,7 @@ gst_rtp_theora_pay_handle_buffer (GstBaseRTPPayload * basepayload,
 
   if (rtptheorapay->need_headers) {
     /* we need to collect the headers and construct a config string from them */
-    if (TDT == 2) {
-      GST_DEBUG_OBJECT (rtptheorapay,
-          "discard comment packet while collecting headers");
-      ret = GST_FLOW_OK;
-      goto done;
-    } else if (TDT != 0) {
+    if (TDT != 0) {
       GST_DEBUG_OBJECT (rtptheorapay, "collecting header, buffer %p", buffer);
       /* append header to the list of headers */
       rtptheorapay->headers = g_list_append (rtptheorapay->headers, buffer);
index a4fd209..dfcb78e 100644 (file)
@@ -81,9 +81,6 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("audio/x-vorbis")
     );
 
-/* 30 bytes for the vorbis identification packet length */
-#define VORBIS_ID_LEN  30
-
 GST_BOILERPLATE (GstRtpVorbisDepay, gst_rtp_vorbis_depay, GstBaseRTPDepayload,
     GST_TYPE_BASE_RTP_DEPAYLOAD);
 
@@ -247,17 +244,26 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
   /*  0                   1                   2                   3
    *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |                   Ident                       |              ..
+   * |                   Ident                       | length       ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..              | n. of headers |    length1    |    length2   ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..              |             Identification Header            ..
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * .................................................................
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * ..   length     |              Identification Header           ..
+   * ..              |         Comment Header                       ..
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * ..                    Identification Header                     |
+   * .................................................................
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * ..                        Comment Header                        |
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * |                          Setup Header                        ..
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * .................................................................
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * ..                         Setup Header                         |
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   *
    */
   for (i = 0; i < num_headers; i++) {
     guint32 ident;