gst/rtp/Makefile.am: gst/rtp/fnv1hash.c (MASK_24, FNV1_HASH_32_INIT, FNV1_HASH_32_PRIME, fnv1_hash_32_new, fnv1_hash_...

Original commit message from CVS:
* gst/rtp/Makefile.am:
* gst/rtp/fnv1hash.c (MASK_24, FNV1_HASH_32_INIT, FNV1_HASH_32_PRIME,
fnv1_hash_32_new, fnv1_hash_32_update, fnv1_hash_32_to_24):
* gst/rtp/fnv1hash.h (__GST_FNV1_HASH_H__):
Add a simple hashing implementation that we can use to generate
a 24-bit ident value based on the codebooks for vorbis and theora.
* gst/rtp/gstrtptheorapay.c (gst_rtp_theora_pay_finish_headers,
gst_rtp_theora_pay_handle_buffer):
* gst/rtp/gstrtpvorbisdepay.c
(gst_rtp_vorbis_depay_parse_configuration,
gst_rtp_vorbis_depay_switch_codebook, gst_rtp_vorbis_depay_process):
* gst/rtp/gstrtpvorbispay.c (gst_rtp_vorbis_pay_reset_packet,
gst_rtp_vorbis_pay_init_packet, gst_rtp_vorbis_pay_flush_packet,
gst_rtp_vorbis_pay_finish_headers, gst_rtp_vorbis_pay_handle_buffer):
Use the hashing function, ensuring that the same codebooks result
in the same ident and thus the same SDP description.
Various log fixes/changes.
This commit is contained in:
Thomas Vander Stichele 2007-04-12 11:41:11 +00:00
parent a7efc5ceb7
commit 2fc868841f
7 changed files with 151 additions and 13 deletions

View file

@ -1,3 +1,23 @@
2007-04-12 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/rtp/Makefile.am:
* gst/rtp/fnv1hash.c (MASK_24, FNV1_HASH_32_INIT, FNV1_HASH_32_PRIME,
fnv1_hash_32_new, fnv1_hash_32_update, fnv1_hash_32_to_24):
* gst/rtp/fnv1hash.h (__GST_FNV1_HASH_H__):
Add a simple hashing implementation that we can use to generate
a 24-bit ident value based on the codebooks for vorbis and theora.
* gst/rtp/gstrtptheorapay.c (gst_rtp_theora_pay_finish_headers,
gst_rtp_theora_pay_handle_buffer):
* gst/rtp/gstrtpvorbisdepay.c
(gst_rtp_vorbis_depay_parse_configuration,
gst_rtp_vorbis_depay_switch_codebook, gst_rtp_vorbis_depay_process):
* gst/rtp/gstrtpvorbispay.c (gst_rtp_vorbis_pay_reset_packet,
gst_rtp_vorbis_pay_init_packet, gst_rtp_vorbis_pay_flush_packet,
gst_rtp_vorbis_pay_finish_headers, gst_rtp_vorbis_pay_handle_buffer):
Use the hashing function, ensuring that the same codebooks result
in the same ident and thus the same SDP description.
Various log fixes/changes.
2007-04-12 Wim Taymans <wim@fluendo.com>
Patch by: jerry tan <jerry dot tan at sun dot com>

View file

@ -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 \

61
gst/rtp/fnv1hash.c Normal file
View file

@ -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);
}

36
gst/rtp/fnv1hash.h Normal file
View file

@ -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__ */

View file

@ -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;

View file

@ -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) {

View file

@ -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;