rmdemux: add better sipr nibble swap routine
This commit is contained in:
parent
a68951f0bb
commit
4044046ac1
@ -261,6 +261,8 @@ gst_rmdemux_init (GstRMDemux * rmdemux)
|
|||||||
rmdemux->first_ts = GST_CLOCK_TIME_NONE;
|
rmdemux->first_ts = GST_CLOCK_TIME_NONE;
|
||||||
rmdemux->base_ts = GST_CLOCK_TIME_NONE;
|
rmdemux->base_ts = GST_CLOCK_TIME_NONE;
|
||||||
rmdemux->need_newsegment = TRUE;
|
rmdemux->need_newsegment = TRUE;
|
||||||
|
|
||||||
|
gst_rm_utils_run_tests ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include "rmutils.h"
|
#include "rmutils.h"
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
@ -141,7 +142,69 @@ gst_rm_utils_descramble_dnet_buffer (GstBuffer * buf)
|
|||||||
return 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},
|
{0, 63}, {1, 22}, {2, 44}, {3, 90},
|
||||||
{5, 81}, {7, 31}, {8, 86}, {9, 58},
|
{5, 81}, {7, 31}, {8, 86}, {9, 58},
|
||||||
{10, 36}, {12, 68}, {13, 39}, {14, 73},
|
{10, 36}, {12, 68}, {13, 39}, {14, 73},
|
||||||
@ -161,30 +224,66 @@ gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf)
|
|||||||
guint size;
|
guint size;
|
||||||
gint n, bs;
|
gint n, bs;
|
||||||
|
|
||||||
|
size = GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
|
/* split the packet in 96 blocks of nibbles */
|
||||||
|
bs = size * 2 / 96;
|
||||||
|
if (bs == 0)
|
||||||
|
return buf;
|
||||||
|
|
||||||
buf = gst_buffer_make_writable (buf);
|
buf = gst_buffer_make_writable (buf);
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buf);
|
data = GST_BUFFER_DATA (buf);
|
||||||
size = GST_BUFFER_SIZE (buf);
|
|
||||||
|
|
||||||
bs = size * 2 / 96;
|
|
||||||
|
|
||||||
|
/* we need to perform 38 swaps on the blocks */
|
||||||
for (n = 0; n < 38; n++) {
|
for (n = 0; n < 38; n++) {
|
||||||
int j;
|
gint idx1, idx2;
|
||||||
int i = bs * sipr_swaps[n][0];
|
|
||||||
int o = bs * sipr_swaps[n][1];
|
|
||||||
|
|
||||||
/* swap 4bit-nibbles of block 'i' with 'o' */
|
/* get the indexes of the blocks of nibbles that need swapping */
|
||||||
for (j = 0; j < bs; j++, i++, o++) {
|
idx1 = bs * sipr_swap_index[n][0];
|
||||||
int x, y;
|
idx2 = bs * sipr_swap_index[n][1];
|
||||||
|
|
||||||
x = (data[i >> 1] >> (4 * (i & 1))) & 0xF;
|
/* swap the blocks */
|
||||||
y = (data[o >> 1] >> (4 * (o & 1))) & 0xF;
|
gst_rm_utils_swap_nibbles (data, idx1, idx2, bs);
|
||||||
|
|
||||||
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))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return buf;
|
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
|
||||||
|
}
|
||||||
|
@ -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_dnet_buffer (GstBuffer * buf);
|
||||||
GstBuffer *gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf);
|
GstBuffer *gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf);
|
||||||
|
|
||||||
|
void gst_rm_utils_run_tests (void);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_RM_UTILS_H__ */
|
#endif /* __GST_RM_UTILS_H__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user