summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2010-05-13 20:24:14 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2010-05-13 20:24:14 +0200
commitffd5b8f1f3865d25cf53ccae746e14a0f71efedc (patch)
treecd4d8d28186eb019e3dfb37c9d8d069e0ed47bca
parenta68951f0bbd2f7ff34b7c83c93adc29166ad08df (diff)
rmutil: WIP try to make a better reorder functionreorder
-rw-r--r--gst/realmedia/rmutils.c121
1 files changed, 108 insertions, 13 deletions
diff --git a/gst/realmedia/rmutils.c b/gst/realmedia/rmutils.c
index b1184257..d8c5110f 100644
--- a/gst/realmedia/rmutils.c
+++ b/gst/realmedia/rmutils.c
@@ -141,7 +141,7 @@ gst_rm_utils_descramble_dnet_buffer (GstBuffer * buf)
return buf;
}
-static const gint sipr_swaps[38][2] = {
+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},
@@ -154,37 +154,132 @@ static const gint sipr_swaps[38][2] = {
{67, 83}, {77, 80}
};
+#define NIBBLE_BYTE(d,idx) (d[(idx)>>1])
+#define NIBBLE_BMASK(d,idx) (NIBBLE_BYTE(d,idx) & (0xf << ((!((idx)&1))<<2)))
+#define NIBBLE_INSERT(v,idx) ((v) << (((idx)&1)<<2))
+#define NIBBLE_EXTRACT(v,idx) ((v) >> (((idx)&1)<<2))
+#define NIBBLE_GET(d,idx) (NIBBLE_EXTRACT (NIBBLE_BYTE (d,idx), idx))
+#define NIBBLE_PUT(d,idx,v) (NIBBLE_BYTE (d,idx) = NIBBLE_BMASK(d,idx) | NIBBLE_INSERT (v,idx))
+
+typedef struct
+{
+ guint8 *data;
+ guint offset;
+ guint8 byte;
+ guint8 store;
+} NibbleParse;
+
+static void
+nibble_parse_init (NibbleParse * parse, guint8 * data, guint nibble)
+{
+ parse->data = data;
+ parse->offset = nibble;
+ parse->byte = data[nibble >> 1];
+ parse->store = parse->byte;
+}
+
+static guint8
+nibble_parse_get (NibbleParse * parse)
+{
+ return parse->byte & 0xf;
+}
+
+static void
+nibble_parse_next (NibbleParse * parse)
+{
+ guint8 res;
+
+ if (parse->offset & 1) {
+ parse->byte >>= 4;
+ } else {
+ parse->byte = parse->data[parse->offset >> 1];
+ parse->store = parse->byte;
+ }
+ parse->offset++;
+
+ return res;
+}
+
+static void
+nibble_parse_store (NibbleParse * parse, guint8 value)
+{
+ parse->store = (parse->store << 4) | value;
+
+ parse->offset++;
+ if (parse->offset & 1) {
+ parse->data[parse->offset >> 1] = parse->byte;
+ }
+}
+
GstBuffer *
gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf)
{
guint8 *data;
guint size;
gint n, bs;
+ NibbleParse pi, po;
buf = gst_buffer_make_writable (buf);
data = GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf);
+ /* split the packet in 96 nibbles */
bs = size * 2 / 96;
+ /* we need to swap the nibles of the blocks */
for (n = 0; n < 38; n++) {
- int j;
- int i = bs * sipr_swaps[n][0];
- int o = bs * sipr_swaps[n][1];
+ gint j, i_idx, o_idx;
+
+ /* get the indexes of the blocks of nibbles that need swapping */
+ i_idx = bs * sipr_swap_index[n][0];
+ o_idx = bs * sipr_swap_index[n][1];
+
+#if 0
+ /* check if we have byte aligned offsets and we can copy bytes */
+ if ((i_idx & 1) == 0 && (o_idx & 1) == 0) {
+ guint8 *i, *o, tmp1, tmp2;
+
+ i = data + (i_idx >> 1);
+ o = data + (o_idx >> 1);
+
+ for (j = bs >> 1; j > 0; j--, i++, o++) {
+ tmp = *i;
+ *i = *o;
+ *o = tmp;
+ }
+ if (bs & 1) {
+ tmp = *i;
+ tmp2 = *o;
+ *i = (tmp2 & 0xf0) | (tmp1 & 0x0f);
+ *o = (tmp1 & 0xf0) | (tmp2 & 0x0f);
+ }
+ } else {
+ for (j = 0; j < bs; j++, i_idx++, o_idx++) {
+ int i, o;
+
+ i = NIBBLE_GET (data, i_idx);
+ o = NIBBLE_GET (data, o_idx);
+
+ NIBBLE_PUT (data, i_idx, o);
+ NIBBLE_PUT (data, o_idx, i);
+ }
+ }
+#else
- /* swap 4bit-nibbles of block 'i' with 'o' */
- for (j = 0; j < bs; j++, i++, o++) {
- int x, y;
+ nibble_parse_init (&pi, data, i_idx);
+ nibble_parse_init (&po, data, o_idx);
- x = (data[i >> 1] >> (4 * (i & 1))) & 0xF;
- y = (data[o >> 1] >> (4 * (o & 1))) & 0xF;
+ for (j = bs; j > 0; j--) {
+ guint8 tmp1, tmp2;
- 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))));
+ tmp1 = nibble_parse_next (&pi);
+ tmp2 = nibble_parse_next (&po);
+
+ nibble_parse_store (&pi, tmp2);
+ nibble_parse_store (&po, tmp1);
}
+#endif
}
return buf;
}