diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2015-12-30 11:47:44 +0100 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2015-12-30 11:55:03 +0100 |
commit | c0f0342596ea6e6faecb0d3cf4be692fa999eb4e (patch) | |
tree | fb16770a58e2f9cdd20a2a68c5a9271f9ae9dc05 | |
parent | 5e2e0442e0fd0f4d6cfaed7049d4dad2139d7d4c (diff) |
libgsmhr: Make it safe to decode/encode different streams at once
Basically the reference code has a bunch of global state.
With some minimal patchihg (previous commit) we can ensure that all
that state is within .bss
So what we do it to save/restore the bss section between calls of the
reference code so we can process several in // and we don't have to
completely fix all reference to global state in the reference codec.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r-- | libgsmhr/Makefile.am | 1 | ||||
-rw-r--r-- | libgsmhr/libgsmhr.c | 33 |
2 files changed, 34 insertions, 0 deletions
diff --git a/libgsmhr/Makefile.am b/libgsmhr/Makefile.am index 15166b4..e6d246d 100644 --- a/libgsmhr/Makefile.am +++ b/libgsmhr/Makefile.am @@ -19,6 +19,7 @@ $(REFSRC_SRC) libgsmhr.c: ${REFSRC_PATH}/.downloaded lib_LTLIBRARIES = libgsmhr.la libgsmhr_la_SOURCES = $(REFSRC_SRC) libgsmhr.c +libgsmhr_la_LIBADD = -ldl clean-local: -rm -rf ${REFSRC_PATH}/*.{c,h} ${REFSRC_PATH}/.downloaded diff --git a/libgsmhr/libgsmhr.c b/libgsmhr/libgsmhr.c index d018c90..eca0ce0 100644 --- a/libgsmhr/libgsmhr.c +++ b/libgsmhr/libgsmhr.c @@ -21,6 +21,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <dlfcn.h> #include <gsmhr/gsmhr.h> @@ -35,12 +36,21 @@ struct gsmhr { int dec_reset_flg; + + void *bss_base; + void *bss_save; + unsigned bss_len; }; EXPORT struct gsmhr * gsmhr_init(void) { struct gsmhr *state; + void *lib; + + lib = dlopen("libgsmhr.so.0", RTLD_NOW | RTLD_NOLOAD); + if (!lib) + return NULL; state = calloc(1, sizeof(struct gsmhr)); if (!state) @@ -48,6 +58,21 @@ gsmhr_init(void) state->dec_reset_flg = 1; + state->bss_base = dlsym(lib, "__bss_start"); + state->bss_len = dlsym(lib, "_end") - state->bss_base; + state->bss_save = malloc(state->bss_len); + + if (!state->bss_save) + { + free(state); + return NULL; + } + + resetDec(); + resetEnc(); + + memcpy(state->bss_save, state->bss_base, state->bss_len); + return state; } @@ -63,6 +88,8 @@ gsmhr_encode(struct gsmhr *state, int16_t *hr_params, const int16_t *pcm) int enc_reset_flg; Shortword pcm_b[F_LEN]; + memcpy(state->bss_base, state->bss_save, state->bss_len); + memcpy(pcm_b, pcm, F_LEN*sizeof(int16_t)); enc_reset_flg = encoderHomingFrameTest(pcm_b); @@ -72,6 +99,8 @@ gsmhr_encode(struct gsmhr *state, int16_t *hr_params, const int16_t *pcm) if (enc_reset_flg) resetEnc(); + memcpy(state->bss_save, state->bss_base, state->bss_len); + return 0; } @@ -84,6 +113,8 @@ gsmhr_decode(struct gsmhr *state, int16_t *pcm, const int16_t *hr_params) int dec_reset_flg; Shortword hr_params_b[22]; + memcpy(state->bss_base, state->bss_save, state->bss_len); + memcpy(hr_params_b, hr_params, 22*sizeof(int16_t)); if (state->dec_reset_flg) @@ -107,5 +138,7 @@ gsmhr_decode(struct gsmhr *state, int16_t *pcm, const int16_t *hr_params) state->dec_reset_flg = dec_reset_flg; + memcpy(state->bss_save, state->bss_base, state->bss_len); + return 0; } |