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>
This commit is contained in:
Sylvain Munaut 2015-12-30 11:47:44 +01:00
parent 5e2e0442e0
commit c0f0342596
2 changed files with 34 additions and 0 deletions

View File

@ -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

View File

@ -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;
}