diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2010-05-13 20:24:14 +0200 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2010-05-13 20:24:14 +0200 |
commit | ffd5b8f1f3865d25cf53ccae746e14a0f71efedc (patch) | |
tree | cd4d8d28186eb019e3dfb37c9d8d069e0ed47bca | |
parent | a68951f0bbd2f7ff34b7c83c93adc29166ad08df (diff) |
rmutil: WIP try to make a better reorder functionreorder
-rw-r--r-- | gst/realmedia/rmutils.c | 121 |
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; } |