summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
Diffstat (limited to 'gst')
-rw-r--r--gst/rtp/Makefile.am2
-rw-r--r--gst/rtp/fnv1hash.c61
-rw-r--r--gst/rtp/fnv1hash.h36
-rw-r--r--gst/rtp/gstrtptheorapay.c19
-rw-r--r--gst/rtp/gstrtpvorbisdepay.c6
-rw-r--r--gst/rtp/gstrtpvorbispay.c20
6 files changed, 131 insertions, 13 deletions
diff --git a/gst/rtp/Makefile.am b/gst/rtp/Makefile.am
index 6f4acefe..3a2be689 100644
--- a/gst/rtp/Makefile.am
+++ b/gst/rtp/Makefile.am
@@ -1,6 +1,7 @@
plugin_LTLIBRARIES = libgstrtp.la
libgstrtp_la_SOURCES = \
+ fnv1hash.c \
gstrtp.c \
gstrtpdepay.c \
gstrtpac3depay.c \
@@ -54,6 +55,7 @@ libgstrtp_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
libgstrtp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = \
+ fnv1hash.h \
gstrtpL16depay.h \
gstrtpL16pay.h \
gstrtpac3depay.h \
diff --git a/gst/rtp/fnv1hash.c b/gst/rtp/fnv1hash.c
new file mode 100644
index 00000000..84fac9ad
--- /dev/null
+++ b/gst/rtp/fnv1hash.c
@@ -0,0 +1,61 @@
+/* GStreamer
+ * Copyright (C) 2007 Thomas Vander Stichele <thomas at apestaart dot org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+
+/* This file implements FNV-1 hashing used in the Ogg payload encoders
+ * to generate the 24-bit ident value based on the header pages.
+ * See http://isthe.com/chongo/tech/comp/fnv/
+ */
+
+#define MASK_24 (((guint32) 1 << 24) -1)
+
+#define FNV1_HASH_32_INIT ((guint32) 0x811C9DC5L)
+//2166136261L)
+#define FNV1_HASH_32_PRIME 16777619
+
+guint32
+fnv1_hash_32_new (void)
+{
+ return FNV1_HASH_32_INIT;
+}
+
+guint32
+fnv1_hash_32_update (guint32 hash, const guchar * data, guint length)
+{
+ guint i;
+ const guchar *p = data;
+
+ for (i = 0; i < length; ++i, ++p) {
+ hash *= FNV1_HASH_32_PRIME;
+ hash ^= *p;
+ }
+
+ return hash;
+}
+
+guint32
+fnv1_hash_32_to_24 (guint32 hash)
+{
+ return (hash >> 24) ^ (hash & MASK_24);
+}
diff --git a/gst/rtp/fnv1hash.h b/gst/rtp/fnv1hash.h
new file mode 100644
index 00000000..ea3c6b6b
--- /dev/null
+++ b/gst/rtp/fnv1hash.h
@@ -0,0 +1,36 @@
+/* GStreamer
+ * Copyright (C) 2007 Thomas Vander Stichele <thomas at apestaart dot org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_FNV1_HASH_H__
+#define __GST_FNV1_HASH_H__
+
+#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
+#include <gst/base/gstadapter.h>
+
+G_BEGIN_DECLS
+
+guint32 fnv1_hash_32_new ();
+guint32 fnv1_hash_32_update (guint32 hash, const guchar *data, guint length);
+guint32 fnv1_hash_32_to_24 (guint32 hash);
+
+G_END_DECLS
+
+#endif /* __GST_FNV1_HASH_H__ */
+
diff --git a/gst/rtp/gstrtptheorapay.c b/gst/rtp/gstrtptheorapay.c
index db8a5872..418b9f0c 100644
--- a/gst/rtp/gstrtptheorapay.c
+++ b/gst/rtp/gstrtptheorapay.c
@@ -25,6 +25,7 @@
#include <gst/rtp/gstrtpbuffer.h>
+#include "fnv1hash.h"
#include "gstrtptheorapay.h"
#define THEORA_ID_LEN 42
@@ -230,8 +231,11 @@ gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
goto no_headers;
/* we need exactly 2 header packets */
- if (g_list_length (rtptheorapay->headers) != 2)
+ 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 |
@@ -266,9 +270,13 @@ gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
/* count the size of the headers first */
length = 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),
+ GST_BUFFER_SIZE (buf));
length += GST_BUFFER_SIZE (buf);
}
@@ -283,8 +291,8 @@ gst_rtp_theora_pay_finish_headers (GstBaseRTPPayload * basepayload)
data[2] = 0;
data[3] = 1;
- /* we generate a random ident for this configuration */
- ident = rtptheorapay->payload_ident = g_random_int ();
+ ident = fnv1_hash_32_to_24 (ident);
+ rtptheorapay->payload_ident = ident;
/* take lower 3 bytes */
data[4] = (ident >> 16) & 0xff;
@@ -427,7 +435,8 @@ gst_rtp_theora_pay_handle_buffer (GstBaseRTPPayload * basepayload,
if (data[0] & 0x80) {
/* header */
if (data[0] == 0x80) {
- /* identification, we need to parse this in order to get the clock rate. */
+ /* identification, we need to parse this in order to get the clock rate.
+ */
if (G_UNLIKELY (!gst_rtp_theora_pay_parse_id (basepayload, data, size)))
goto parse_id_failed;
TDT = 1;
@@ -451,7 +460,7 @@ gst_rtp_theora_pay_handle_buffer (GstBaseRTPPayload * basepayload,
ret = GST_FLOW_OK;
goto done;
} else if (TDT != 0) {
- GST_DEBUG_OBJECT (rtptheorapay, "collecting header");
+ GST_DEBUG_OBJECT (rtptheorapay, "collecting header, buffer %p", buffer);
/* append header to the list of headers */
rtptheorapay->headers = g_list_append (rtptheorapay->headers, buffer);
ret = GST_FLOW_OK;
diff --git a/gst/rtp/gstrtpvorbisdepay.c b/gst/rtp/gstrtpvorbisdepay.c
index eab62100..d71c72ac 100644
--- a/gst/rtp/gstrtpvorbisdepay.c
+++ b/gst/rtp/gstrtpvorbisdepay.c
@@ -227,7 +227,7 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
size -= 5;
data += 5;
- GST_DEBUG_OBJECT (rtpvorbisdepay, "header %d, ident %08x, length %u", i,
+ GST_DEBUG_OBJECT (rtpvorbisdepay, "header %d, ident 0x%08x, length %u", i,
ident, length);
if (size < length + VORBIS_ID_LEN)
@@ -363,6 +363,7 @@ gst_rtp_vorbis_depay_switch_codebook (GstRtpVorbisDepay * rtpvorbisdepay,
GList *walk;
gboolean res = FALSE;
+ GST_DEBUG_OBJECT (rtpvorbisdepay, "Looking up code book ident 0x%08x", ident);
for (walk = rtpvorbisdepay->configs; walk; walk = g_list_next (walk)) {
GstRtpVorbisConfig *conf = (GstRtpVorbisConfig *) walk->data;
@@ -436,6 +437,7 @@ gst_rtp_vorbis_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (G_UNLIKELY (VDT == 3))
goto ignore_reserved;
+ GST_DEBUG_OBJECT (depayload, "header: 0x%08x", header);
ident = (header >> 8) & 0xffffff;
F = (header & 0xc0) >> 6;
packets = (header & 0xf);
@@ -447,9 +449,11 @@ gst_rtp_vorbis_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (!rtpvorbisdepay->config) {
/* we don't have an active codebook, find the codebook and
* activate it */
+ GST_DEBUG_OBJECT (rtpvorbisdepay, "No active codebook, switching");
do_switch = TRUE;
} else if (rtpvorbisdepay->config->ident != ident) {
/* codebook changed */
+ GST_DEBUG_OBJECT (rtpvorbisdepay, "codebook changed, switching");
do_switch = TRUE;
}
if (do_switch) {
diff --git a/gst/rtp/gstrtpvorbispay.c b/gst/rtp/gstrtpvorbispay.c
index 0482e0c5..35478a27 100644
--- a/gst/rtp/gstrtpvorbispay.c
+++ b/gst/rtp/gstrtpvorbispay.c
@@ -25,6 +25,7 @@
#include <gst/rtp/gstrtpbuffer.h>
+#include "fnv1hash.h"
#include "gstrtpvorbispay.h"
GST_DEBUG_CATEGORY_STATIC (rtpvorbispay_debug);
@@ -133,7 +134,7 @@ gst_rtp_vorbis_pay_reset_packet (GstRtpVorbisPay * rtpvorbispay, guint8 VDT)
{
guint payload_len;
- GST_DEBUG_OBJECT (rtpvorbispay, "reset packet");
+ GST_LOG_OBJECT (rtpvorbispay, "reset packet");
rtpvorbispay->payload_pos = 4;
payload_len = gst_rtp_buffer_get_payload_len (rtpvorbispay->packet);
@@ -148,7 +149,7 @@ static void
gst_rtp_vorbis_pay_init_packet (GstRtpVorbisPay * rtpvorbispay, guint8 VDT,
GstClockTime timestamp)
{
- GST_DEBUG_OBJECT (rtpvorbispay, "starting new packet, VDT: %d", VDT);
+ GST_LOG_OBJECT (rtpvorbispay, "starting new packet, VDT: %d", VDT);
if (rtpvorbispay->packet)
gst_buffer_unref (rtpvorbispay->packet);
@@ -172,7 +173,7 @@ gst_rtp_vorbis_pay_flush_packet (GstRtpVorbisPay * rtpvorbispay)
if (!rtpvorbispay->packet || rtpvorbispay->payload_pos <= 4)
return GST_FLOW_OK;
- GST_DEBUG_OBJECT (rtpvorbispay, "flushing packet");
+ GST_LOG_OBJECT (rtpvorbispay, "flushing packet");
/* fix header */
payload = gst_rtp_buffer_get_payload (rtpvorbispay->packet);
@@ -261,9 +262,13 @@ gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload)
/* count the size of the headers first */
length = 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),
+ GST_BUFFER_SIZE (buf));
length += GST_BUFFER_SIZE (buf);
}
@@ -278,8 +283,9 @@ gst_rtp_vorbis_pay_finish_headers (GstBaseRTPPayload * basepayload)
data[2] = 0;
data[3] = 1;
- /* we generate a random ident for this configuration */
- ident = rtpvorbispay->payload_ident = g_random_int ();
+ ident = fnv1_hash_32_to_24 (ident);
+ rtpvorbispay->payload_ident = ident;
+ GST_DEBUG_OBJECT (rtpvorbispay, "ident 0x%08x", ident);
/* take lower 3 bytes */
data[4] = (ident >> 16) & 0xff;
@@ -416,7 +422,7 @@ gst_rtp_vorbis_pay_handle_buffer (GstBaseRTPPayload * basepayload,
duration = GST_BUFFER_DURATION (buffer);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
- GST_DEBUG_OBJECT (rtpvorbispay, "size %u, duration %" GST_TIME_FORMAT,
+ GST_LOG_OBJECT (rtpvorbispay, "size %u, duration %" GST_TIME_FORMAT,
size, GST_TIME_ARGS (duration));
if (G_UNLIKELY (size < 1 || size > 0xffff))
@@ -496,7 +502,7 @@ gst_rtp_vorbis_pay_handle_buffer (GstBaseRTPPayload * basepayload,
while (size) {
plen = MIN (rtpvorbispay->payload_left - 2, size);
- GST_DEBUG_OBJECT (rtpvorbispay, "append %u bytes", plen);
+ GST_LOG_OBJECT (rtpvorbispay, "append %u bytes", plen);
/* data is copied in the payload with a 2 byte length header */
ppos[0] = (plen >> 8) & 0xff;