#include "config.h"
#endif
+#include <string.h>
#include "rmutils.h"
gchar *
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},
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
+}