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.
This commit is contained in:
Wim Taymans 2007-05-11 15:04:38 +00:00
parent 3e1fd61201
commit 5bc71b661d
5 changed files with 276 additions and 93 deletions

View file

@ -1,3 +1,17 @@
2007-05-11 Wim Taymans <wim@fluendo.com>
* 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.
2007-05-11 Wim Taymans <wim@fluendo.com> 2007-05-11 Wim Taymans <wim@fluendo.com>
* gst/rtsp/rtsptransport.c: * gst/rtsp/rtsptransport.c:

2
common

@ -1 +1 @@
Subproject commit 1b4fb5836a9e290fe13895643d41e0166de8a94c Subproject commit b5971d76ccd216c27e095c02c3a369a9d05cb36d

View file

@ -22,16 +22,41 @@ The following fields can or must (*) be specified in the structure:
set. set.
* clock-rate: (int) [0 - MAXINT] * clock-rate: (int) [0 - MAXINT]
the RTP clock rate The RTP clock rate.
ssrc: (uint) [0 - MAXINT] ssrc: (uint) [0 - MAXINT]
The ssrc value currently in use. The ssrc value currently in use. (default = the SSRC of the first RTP
packet)
npt-start: (uint64) [0 - MAXINT]
The Normal Play Time for clock-base. This is the position in the stream and
is between 0 and the duration of the stream. This value is expressed in
nanoseconds GstClockTime. (default = 0)
npt-stop: (uint64) [0 - MAXINT]
The last position in the stream. This value is expressed in nanoseconds
GstClockTime. (default = -1, stop unknown)
clock-base: (uint) [0 - MAXINT] clock-base: (uint) [0 - MAXINT]
The RTP time representing time 0 The RTP time representing time npt-start. (default = rtptime of first RTP
packet).
play-speed: (gdouble) [-MIN - MAX]
The intended playback speed of the stream. The client is delivered data at
the adjusted speed. The client should adjust its playback speed with this
value and thus corresponds to the GStreamer rate field in the NEWSEGMENT
event. (default = 1.0)
play-scale: (gdouble) [-MIN - MAX]
The rate already applied to the stream. The client is delivered a stream
that is scaled by this amount. This value is used to adjust position
reporting and corresponds to the GStream applied-rate field in the
NEWSEGMENT event. (default = 1.0)
seqnum-base: (uint) [0 - MAXINT] seqnum-base: (uint) [0 - MAXINT]
The RTP sequence number representing the first rtp packet The RTP sequence number representing the first rtp packet. When this
parameter is given, all sequence numbers below this seqnum should be
ignored. (default = seqnum of first RTP packet).
encoding-name: (String) ANY encoding-name: (String) ANY
typically second part of the mime type. ex. MP4V-ES. only required if typically second part of the mime type. ex. MP4V-ES. only required if
@ -50,15 +75,15 @@ The following fields can or must (*) be specified in the structure:
Example: Example:
"application/x-rtp", "application/x-rtp",
"media", G_TYPE_STRING, "audio", -] "media", G_TYPE_STRING, "audio", -.
"payload", G_TYPE_INT, 96, ] - required "payload", G_TYPE_INT, 96, | - required
"clock-rate", G_TYPE_INT, 8000, -] "clock-rate", G_TYPE_INT, 8000, -'
"encoding-name", G_TYPE_STRING, "AMR", -] - required since payload >= 96 "encoding-name", G_TYPE_STRING, "AMR", -. - required since payload >= 96
"encoding-params", G_TYPE_STRING, "1", -] - optional param for AMR "encoding-params", G_TYPE_STRING, "1", -' - optional param for AMR
"octet-align", G_TYPE_STRING, "1", -] "octet-align", G_TYPE_STRING, "1", -.
"crc", G_TYPE_STRING, "0", ] "crc", G_TYPE_STRING, "0", |
"robust-sorting", G_TYPE_STRING, "0", ] AMR specific params. "robust-sorting", G_TYPE_STRING, "0", | AMR specific params.
"interleaving", G_TYPE_STRING, "0", -] "interleaving", G_TYPE_STRING, "0", -'
Mapping of caps to and from SDP fields: Mapping of caps to and from SDP fields:
@ -79,6 +104,18 @@ The following fields can or must (*) be specified in the structure:
always use the lowercase names so that the SDP -> caps mapping remains always use the lowercase names so that the SDP -> caps mapping remains
possible. possible.
Mapping of caps to NEWSEGMENT:
rate: <play-speed>
applied-rate: <play-scale>
format: GST_FORMAT_TIME
start: <clock-base> * GST_SECOND / <clock-rate>
stop: if <ntp-stop> != -1
<npt-stop> - <npt-start> + start
else
-1
time: <npt-start>
usage with UDP usage with UDP
-------------- --------------

View file

@ -30,11 +30,15 @@
GST_DEBUG_CATEGORY_STATIC (rtpvorbisdepay_debug); GST_DEBUG_CATEGORY_STATIC (rtpvorbisdepay_debug);
#define GST_CAT_DEFAULT (rtpvorbisdepay_debug) #define GST_CAT_DEFAULT (rtpvorbisdepay_debug)
/* references:
* http://svn.xiph.org/trunk/vorbis/doc/draft-ietf-avt-rtp-vorbis-04.txt
*/
/* elementfactory information */ /* elementfactory information */
static const GstElementDetails gst_rtp_vorbis_depay_details = static const GstElementDetails gst_rtp_vorbis_depay_details =
GST_ELEMENT_DETAILS ("RTP packet depayloader", GST_ELEMENT_DETAILS ("RTP packet depayloader",
"Codec/Depayloader/Network", "Codec/Depayloader/Network",
"Extracts Vorbis Audio from RTP packets (draft-01 of RFC XXXX)", "Extracts Vorbis Audio from RTP packets (draft-04 of RFC XXXX)",
"Wim Taymans <wim@fluendo.com>"); "Wim Taymans <wim@fluendo.com>");
/* RtpVorbisDepay signals and args */ /* RtpVorbisDepay signals and args */
@ -151,28 +155,70 @@ gst_rtp_vorbis_depay_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (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 static gboolean
gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay, gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
const gchar * configuration) const gchar * configuration)
{ {
GValue v = { 0 };
GstBuffer *buf; GstBuffer *buf;
guint32 num_headers; guint32 num_headers;
guint8 *data; guint8 *data;
guint size; guint size;
gint i; gint i, j;
/* deserialize base16 to buffer */ /* deserialize base64 to buffer */
g_value_init (&v, GST_TYPE_BUFFER); size = strlen (configuration);
if (!gst_value_deserialize (&v, configuration)) GST_DEBUG_OBJECT (rtpvorbisdepay, "base64 config size %u", size);
goto wrong_configuration;
buf = gst_value_get_buffer (&v); data = g_malloc (size);
gst_buffer_ref (buf); size = decode_base64 (configuration, data);
g_value_unset (&v);
data = GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf);
GST_DEBUG_OBJECT (rtpvorbisdepay, "config size %u", size); GST_DEBUG_OBJECT (rtpvorbisdepay, "config size %u", size);
@ -216,59 +262,73 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
for (i = 0; i < num_headers; i++) { for (i = 0; i < num_headers; i++) {
guint32 ident; guint32 ident;
guint16 length; guint16 length;
guint8 n_headers, b;
GstRtpVorbisConfig *conf; GstRtpVorbisConfig *conf;
GstTagList *list; guint *h_sizes;
if (size < 5) if (size < 6)
goto too_small; goto too_small;
ident = (data[0] << 16) | (data[1] << 8) | data[2]; ident = (data[0] << 16) | (data[1] << 8) | data[2];
length = (data[3] << 8) | data[4]; length = (data[3] << 8) | data[4];
size -= 5; n_headers = data[5];
data += 5; size -= 6;
data += 6;
GST_DEBUG_OBJECT (rtpvorbisdepay, "header %d, ident 0x%08x, length %u", i, GST_DEBUG_OBJECT (rtpvorbisdepay,
ident, length); "header %d, ident 0x%08x, length %u, left %u", i, ident, length, size);
if (size < length + VORBIS_ID_LEN) if (size < length)
goto too_small; goto too_small;
GST_DEBUG_OBJECT (rtpvorbisdepay, "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 (rtpvorbisdepay, "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 (rtpvorbisdepay, "last header size: %u", length);
h_sizes[j] = length;
GST_DEBUG_OBJECT (rtpvorbisdepay, "preparing headers");
conf = g_new0 (GstRtpVorbisConfig, 1); conf = g_new0 (GstRtpVorbisConfig, 1);
conf->ident = ident; conf->ident = ident;
buf = gst_buffer_new_and_alloc (VORBIS_ID_LEN); for (j = 0; j <= n_headers; j++) {
memcpy (GST_BUFFER_DATA (buf), data, VORBIS_ID_LEN); guint h_size;
conf->headers = g_list_append (conf->headers, buf);
data += VORBIS_ID_LEN;
size -= VORBIS_ID_LEN;
/* create a dummy comment */ h_size = h_sizes[j];
list = gst_tag_list_new (); if (size < h_size)
buf = goto too_small;
gst_tag_list_to_vorbiscomment_buffer (list, (guint8 *) "\003vorbis", 7,
"Vorbis RTP depayloader");
conf->headers = g_list_append (conf->headers, buf);
gst_tag_list_free (list);
buf = gst_buffer_new_and_alloc (length); GST_DEBUG_OBJECT (rtpvorbisdepay, "reading header %d, size %u", j,
memcpy (GST_BUFFER_DATA (buf), data, length); h_size);
conf->headers = g_list_append (conf->headers, buf);
data += length;
size -= length;
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;
}
rtpvorbisdepay->configs = g_list_append (rtpvorbisdepay->configs, conf); rtpvorbisdepay->configs = g_list_append (rtpvorbisdepay->configs, conf);
} }
return TRUE; return TRUE;
/* ERRORS */ /* ERRORS */
wrong_configuration:
{
GST_DEBUG_OBJECT (rtpvorbisdepay, "error parsing configuration");
return FALSE;
}
too_small: too_small:
{ {
GST_DEBUG_OBJECT (rtpvorbisdepay, "configuration too small"); GST_DEBUG_OBJECT (rtpvorbisdepay, "configuration too small");
@ -421,6 +481,8 @@ gst_rtp_vorbis_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
payload = gst_rtp_buffer_get_payload (buf); payload = gst_rtp_buffer_get_payload (buf);
free_payload = FALSE; free_payload = FALSE;
gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
header = GST_READ_UINT32_BE (payload); header = GST_READ_UINT32_BE (payload);
/* /*
* 0 1 2 3 * 0 1 2 3

View file

@ -32,7 +32,7 @@ GST_DEBUG_CATEGORY_STATIC (rtpvorbispay_debug);
#define GST_CAT_DEFAULT (rtpvorbispay_debug) #define GST_CAT_DEFAULT (rtpvorbispay_debug)
/* references: /* 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 */ /* elementfactory information */
@ -208,27 +208,47 @@ gst_rtp_vorbis_pay_flush_packet (GstRtpVorbisPay * rtpvorbispay)
return ret; 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 static gboolean
gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload) gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload)
{ {
GstRtpVorbisPay *rtpvorbispay = GST_RTP_VORBIS_PAY (basepayload); GstRtpVorbisPay *rtpvorbispay = GST_RTP_VORBIS_PAY (basepayload);
GList *walk; GList *walk;
guint length; guint length, size, n_headers, configlen;
gchar *cstr, *configuration; gchar *cstr, *configuration;
guint8 *data; guint8 *data, *config;
guint32 ident; guint32 ident;
GValue v = { 0 };
GstBuffer *config;
GST_DEBUG_OBJECT (rtpvorbispay, "finish headers"); GST_DEBUG_OBJECT (rtpvorbispay, "finish headers");
if (!rtpvorbispay->headers) if (!rtpvorbispay->headers)
goto no_headers; goto no_headers;
/* we need exactly 2 header packets */
if (g_list_length (rtpvorbispay->headers) != 2)
goto no_headers;
/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Number of packed 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
* 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 * 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 ..
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* .. length | Identification Header .. * .. | n. of headers | length1 | length2 ..
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* .. Identification Header | * .. | Identification Header ..
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* .................................................................
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* .. | Comment Header ..
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* .................................................................
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* .. Comment Header |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Setup Header .. * | Setup 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; length = 0;
n_headers = 0;
ident = fnv1_hash_32_new (); ident = fnv1_hash_32_new ();
for (walk = rtpvorbispay->headers; walk; walk = g_list_next (walk)) { for (walk = rtpvorbispay->headers; walk; walk = g_list_next (walk)) {
GstBuffer *buf = GST_BUFFER_CAST (walk->data); GstBuffer *buf = GST_BUFFER_CAST (walk->data);
guint bsize;
ident = bsize = GST_BUFFER_SIZE (buf);
fnv1_hash_32_update (ident, GST_BUFFER_DATA (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)); GST_BUFFER_SIZE (buf));
length += GST_BUFFER_SIZE (buf);
} }
/* total config length is 4 bytes header number + size of the /* packet length is header size + packet length */
* headers + 2 bytes length + 3 bytes for the ident */ configlen = size + length;
config = gst_buffer_new_and_alloc (length + 4 + 2 + 3); config = data = g_malloc (configlen);
data = GST_BUFFER_DATA (config);
/* number of packed headers, we only pack 1 header */ /* number of packed headers, we only pack 1 header */
data[0] = 0; data[0] = 0;
@ -292,12 +337,44 @@ gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload)
data[5] = (ident >> 8) & 0xff; data[5] = (ident >> 8) & 0xff;
data[6] = ident & 0xff; data[6] = ident & 0xff;
/* store length minus the length of the fixed vorbis header */ /* store length of all vorbis headers */
data[7] = ((length - 30) >> 8) & 0xff; data[7] = ((length) >> 8) & 0xff;
data[8] = (length - 30) & 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 */ /* copy header data */
data += 9;
for (walk = rtpvorbispay->headers; walk; walk = g_list_next (walk)) { for (walk = rtpvorbispay->headers; walk; walk = g_list_next (walk)) {
GstBuffer *buf = GST_BUFFER_CAST (walk->data); GstBuffer *buf = GST_BUFFER_CAST (walk->data);
@ -305,10 +382,9 @@ gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload)
data += GST_BUFFER_SIZE (buf); data += GST_BUFFER_SIZE (buf);
} }
/* serialize buffer to base16 */ /* serialize to base64 */
g_value_init (&v, GST_TYPE_BUFFER); configuration = encode_base64 (config, configlen, &size);
gst_value_take_buffer (&v, config); g_free (config);
configuration = gst_value_serialize (&v);
/* configure payloader settings */ /* configure payloader settings */
cstr = g_strdup_printf ("%d", rtpvorbispay->channels); cstr = g_strdup_printf ("%d", rtpvorbispay->channels);
@ -322,7 +398,6 @@ gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload)
NULL); NULL);
g_free (cstr); g_free (cstr);
g_free (configuration); g_free (configuration);
g_value_unset (&v);
return TRUE; return TRUE;
@ -450,12 +525,7 @@ gst_rtp_vorbis_pay_handle_buffer (GstBaseRTPPayload * basepayload,
if (rtpvorbispay->need_headers) { if (rtpvorbispay->need_headers) {
/* we need to collect the headers and construct a config string from them */ /* we need to collect the headers and construct a config string from them */
if (VDT == 2) { if (VDT != 0) {
GST_DEBUG_OBJECT (rtpvorbispay,
"discard comment packet while collecting headers");
ret = GST_FLOW_OK;
goto done;
} else if (VDT != 0) {
GST_DEBUG_OBJECT (rtpvorbispay, "collecting header"); GST_DEBUG_OBJECT (rtpvorbispay, "collecting header");
/* append header to the list of headers */ /* append header to the list of headers */
rtpvorbispay->headers = g_list_append (rtpvorbispay->headers, buffer); rtpvorbispay->headers = g_list_append (rtpvorbispay->headers, buffer);