diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2007-05-11 15:04:38 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2007-05-11 15:04:38 +0000 |
commit | 5bc71b661d5f3b3902fc1ccde5026472c75fa2e3 (patch) | |
tree | af0f93b5d4b1025475de4f0b700b36b0cf18521a /gst/rtp/gstrtpvorbispay.c | |
parent | 3e1fd612011cbb0c3d6a71303fbd36f193dadc1a (diff) |
gst/rtp/README: Update README with new RTP variables that will be used for synchronisation.
Original commit message from CVS:
* gst/rtp/README:
Update README with new RTP variables that will be used for
synchronisation.
* gst/rtp/gstrtpvorbisdepay.c: (decode_base64),
(gst_rtp_vorbis_depay_parse_configuration),
(gst_rtp_vorbis_depay_process):
* gst/rtp/gstrtpvorbispay.c: (encode_base64),
(gst_rtp_vorbis_pay_finish_headers),
(gst_rtp_vorbis_pay_handle_buffer):
Update vorbis pay and depayloader to draft-04.
Diffstat (limited to 'gst/rtp/gstrtpvorbispay.c')
-rw-r--r-- | gst/rtp/gstrtpvorbispay.c | 144 |
1 files changed, 107 insertions, 37 deletions
diff --git a/gst/rtp/gstrtpvorbispay.c b/gst/rtp/gstrtpvorbispay.c index 35478a27..f85ee94c 100644 --- a/gst/rtp/gstrtpvorbispay.c +++ b/gst/rtp/gstrtpvorbispay.c @@ -32,7 +32,7 @@ GST_DEBUG_CATEGORY_STATIC (rtpvorbispay_debug); #define GST_CAT_DEFAULT (rtpvorbispay_debug) /* references: - * http://svn.xiph.org/trunk/vorbis/doc/draft-ietf-avt-rtp-vorbis-01.txt + * http://svn.xiph.org/trunk/vorbis/doc/draft-ietf-avt-rtp-vorbis-04.txt */ /* elementfactory information */ @@ -208,27 +208,47 @@ gst_rtp_vorbis_pay_flush_packet (GstRtpVorbisPay * rtpvorbispay) 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_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload) { GstRtpVorbisPay *rtpvorbispay = GST_RTP_VORBIS_PAY (basepayload); GList *walk; - guint length; + guint length, size, n_headers, configlen; gchar *cstr, *configuration; - guint8 *data; + guint8 *data, *config; guint32 ident; - GValue v = { 0 }; - GstBuffer *config; GST_DEBUG_OBJECT (rtpvorbispay, "finish headers"); if (!rtpvorbispay->headers) goto no_headers; - /* we need exactly 2 header packets */ - if (g_list_length (rtpvorbispay->headers) != 2) - goto no_headers; - /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Number of packed headers | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -247,35 +267,60 @@ gst_rtp_vorbis_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 = rtpvorbispay->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; @@ -292,12 +337,44 @@ gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload) data[5] = (ident >> 8) & 0xff; data[6] = ident & 0xff; - /* store length minus the length of the fixed vorbis header */ - data[7] = ((length - 30) >> 8) & 0xff; - data[8] = (length - 30) & 0xff; + /* store length of all vorbis 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 = rtpvorbispay->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 = rtpvorbispay->headers; walk; walk = g_list_next (walk)) { GstBuffer *buf = GST_BUFFER_CAST (walk->data); @@ -305,10 +382,9 @@ gst_rtp_vorbis_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 */ cstr = g_strdup_printf ("%d", rtpvorbispay->channels); @@ -322,7 +398,6 @@ gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload) NULL); g_free (cstr); g_free (configuration); - g_value_unset (&v); return TRUE; @@ -450,12 +525,7 @@ gst_rtp_vorbis_pay_handle_buffer (GstBaseRTPPayload * basepayload, if (rtpvorbispay->need_headers) { /* we need to collect the headers and construct a config string from them */ - if (VDT == 2) { - GST_DEBUG_OBJECT (rtpvorbispay, - "discard comment packet while collecting headers"); - ret = GST_FLOW_OK; - goto done; - } else if (VDT != 0) { + if (VDT != 0) { GST_DEBUG_OBJECT (rtpvorbispay, "collecting header"); /* append header to the list of headers */ rtpvorbispay->headers = g_list_append (rtpvorbispay->headers, buffer); |