From 4044046ac178fa3a34bc08fa32816b9e10b63d2f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 14 May 2010 16:02:47 +0200 Subject: [PATCH] rmdemux: add better sipr nibble swap routine --- gst/realmedia/rmdemux.c | 2 + gst/realmedia/rmutils.c | 135 +++++++++++++++++++++++++++++++++++++++++------- gst/realmedia/rmutils.h | 3 ++ 3 files changed, 122 insertions(+), 18 deletions(-) diff --git a/gst/realmedia/rmdemux.c b/gst/realmedia/rmdemux.c index b180ffa..dd1338c 100644 --- a/gst/realmedia/rmdemux.c +++ b/gst/realmedia/rmdemux.c @@ -261,6 +261,8 @@ gst_rmdemux_init (GstRMDemux * rmdemux) rmdemux->first_ts = GST_CLOCK_TIME_NONE; rmdemux->base_ts = GST_CLOCK_TIME_NONE; rmdemux->need_newsegment = TRUE; + + gst_rm_utils_run_tests (); } static gboolean diff --git a/gst/realmedia/rmutils.c b/gst/realmedia/rmutils.c index b118425..8a110dc 100644 --- a/gst/realmedia/rmutils.c +++ b/gst/realmedia/rmutils.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include "rmutils.h" gchar * @@ -141,7 +142,69 @@ gst_rm_utils_descramble_dnet_buffer (GstBuffer * buf) return buf; } -static const gint sipr_swaps[38][2] = { +static void +gst_rm_utils_swap_nibbles (guint8 * data, gint idx1, gint idx2, gint len) +{ + guint8 *d1, *d2, tmp1, tmp2, tmp1n, tmp2n; + + if ((idx2 & 1) && !(idx1 & 1)) { + /* align destination to a byte by swapping the indexes */ + tmp1 = idx1; + idx1 = idx2; + idx2 = tmp1; + } + d1 = data + (idx1 >> 1); + d2 = data + (idx2 >> 1); + + /* check if we have aligned offsets and we can copy bytes */ + if ((idx1 & 1) == (idx2 & 1)) { + if (idx1 & 1) { + /* swap first nibble */ + tmp1 = *d1; + tmp2 = *d2; + *d1++ = (tmp2 & 0xf0) | (tmp1 & 0x0f); + *d2++ = (tmp1 & 0xf0) | (tmp2 & 0x0f); + len--; + } + for (; len > 1; len -= 2) { + /* swap 2 nibbles */ + tmp1 = *d1; + *d1++ = *d2; + *d2++ = tmp1; + } + if (len) { + /* swap leftover nibble */ + tmp1 = *d1; + tmp2 = *d2; + *d1 = (tmp2 & 0x0f) | (tmp1 & 0xf0); + *d2 = (tmp1 & 0x0f) | (tmp2 & 0xf0); + } + } else { + /* preload nibbles from source */ + tmp2n = tmp1 = tmp1n = *d1; + tmp2 = *d2; + + for (; len > 1; len -= 2) { + /* assemble nibbles */ + *d1++ = (tmp2n & 0x0f) | (tmp2 << 4); + tmp1n = *d1; + *d2++ = (tmp1n << 4) | (tmp1 >> 4); + + tmp1 = tmp1n; + tmp2n = (tmp2 >> 4); + tmp2 = *d2; + } + if (len) { + /* last leftover */ + *d1 = (tmp2 << 4) | (tmp2n & 0x0f); + *d2 = (tmp1 >> 4) | (tmp2 & 0xf0); + } else { + *d1 = (tmp1 & 0xf0) | (tmp2n); + } + } +} + +static const gint sipr_swap_index[38][2] = { {0, 63}, {1, 22}, {2, 44}, {3, 90}, {5, 81}, {7, 31}, {8, 86}, {9, 58}, {10, 36}, {12, 68}, {13, 39}, {14, 73}, @@ -161,30 +224,66 @@ gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf) guint size; gint n, bs; - buf = gst_buffer_make_writable (buf); - - data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); + /* split the packet in 96 blocks of nibbles */ bs = size * 2 / 96; + if (bs == 0) + return buf; - for (n = 0; n < 38; n++) { - int j; - int i = bs * sipr_swaps[n][0]; - int o = bs * sipr_swaps[n][1]; + buf = gst_buffer_make_writable (buf); + + data = GST_BUFFER_DATA (buf); - /* swap 4bit-nibbles of block 'i' with 'o' */ - for (j = 0; j < bs; j++, i++, o++) { - int x, y; + /* we need to perform 38 swaps on the blocks */ + for (n = 0; n < 38; n++) { + gint idx1, idx2; - x = (data[i >> 1] >> (4 * (i & 1))) & 0xF; - y = (data[o >> 1] >> (4 * (o & 1))) & 0xF; + /* get the indexes of the blocks of nibbles that need swapping */ + idx1 = bs * sipr_swap_index[n][0]; + idx2 = bs * sipr_swap_index[n][1]; - data[o >> 1] = (x << (4 * (o & 1))) | - (data[o >> 1] & (0xF << (4 * !(o & 1)))); - data[i >> 1] = (y << (4 * (i & 1))) | - (data[i >> 1] & (0xF << (4 * !(i & 1)))); - } + /* swap the blocks */ + gst_rm_utils_swap_nibbles (data, idx1, idx2, bs); } return buf; } + +void +gst_rm_utils_run_tests (void) +{ +#if 0 + guint8 tab1[] = { 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }; + guint8 tab2[8]; + + memcpy (tab2, tab1, 8); + gst_util_dump_mem (tab2, 8); + + gst_rm_utils_swap_nibbles (tab2, 0, 8, 4); + gst_util_dump_mem (tab2, 8); + memcpy (tab2, tab1, 8); + gst_rm_utils_swap_nibbles (tab2, 0, 8, 5); + gst_util_dump_mem (tab2, 8); + + memcpy (tab2, tab1, 8); + gst_rm_utils_swap_nibbles (tab2, 1, 8, 4); + gst_util_dump_mem (tab2, 8); + memcpy (tab2, tab1, 8); + gst_rm_utils_swap_nibbles (tab2, 1, 8, 5); + gst_util_dump_mem (tab2, 8); + + memcpy (tab2, tab1, 8); + gst_rm_utils_swap_nibbles (tab2, 0, 9, 4); + gst_util_dump_mem (tab2, 8); + memcpy (tab2, tab1, 8); + gst_rm_utils_swap_nibbles (tab2, 0, 9, 5); + gst_util_dump_mem (tab2, 8); + + memcpy (tab2, tab1, 8); + gst_rm_utils_swap_nibbles (tab2, 1, 9, 4); + gst_util_dump_mem (tab2, 8); + memcpy (tab2, tab1, 8); + gst_rm_utils_swap_nibbles (tab2, 1, 9, 5); + gst_util_dump_mem (tab2, 8); +#endif +} diff --git a/gst/realmedia/rmutils.h b/gst/realmedia/rmutils.h index ed0ace5..bd10c5e 100644 --- a/gst/realmedia/rmutils.h +++ b/gst/realmedia/rmutils.h @@ -41,6 +41,9 @@ GstTagList *gst_rm_utils_read_tags (const guint8 * data, GstBuffer *gst_rm_utils_descramble_dnet_buffer (GstBuffer * buf); GstBuffer *gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf); +void gst_rm_utils_run_tests (void); + + G_END_DECLS #endif /* __GST_RM_UTILS_H__ */ -- 2.7.4