diff options
author | Alfred E. Heggestad <aeh@db.org> | 2014-06-29 18:08:27 +0200 |
---|---|---|
committer | Alfred E. Heggestad <aeh@db.org> | 2014-06-29 18:08:27 +0200 |
commit | 2e3d6a0ff8b621cd8536796d88e804d4dac3ee2a (patch) | |
tree | be6d7ffe78ded455b66c4411f63784e2597d4343 /modules/opensles | |
parent | 0e00a48c79154097bdf26035e0814e8388e4f450 (diff) |
opensles: add double-buffering and some tuning
Credits to Francesco Bradascio for the original work.
Diffstat (limited to 'modules/opensles')
-rw-r--r-- | modules/opensles/opensles.c | 6 | ||||
-rw-r--r-- | modules/opensles/player.c | 35 | ||||
-rw-r--r-- | modules/opensles/recorder.c | 104 |
3 files changed, 70 insertions, 75 deletions
diff --git a/modules/opensles/opensles.c b/modules/opensles/opensles.c index 9da39f0..665288c 100644 --- a/modules/opensles/opensles.c +++ b/modules/opensles/opensles.c @@ -20,10 +20,14 @@ static struct ausrc *ausrc; static int module_init(void) { + SLEngineOption engineOption[] = { + { (SLuint32) SL_ENGINEOPTION_THREADSAFE, + (SLuint32) SL_BOOLEAN_TRUE }, + }; SLresult r; int err; - r = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); + r = slCreateEngine(&engineObject, 1, engineOption, 0, NULL, NULL); if (SL_RESULT_SUCCESS != r) return ENODEV; diff --git a/modules/opensles/player.c b/modules/opensles/player.c index c899750..797ae48 100644 --- a/modules/opensles/player.c +++ b/modules/opensles/player.c @@ -10,12 +10,17 @@ #include "opensles.h" +#define N_PLAY_QUEUE_BUFFERS 2 +#define PTIME 10 + + struct auplay_st { struct auplay *ap; /* inheritance */ - int16_t *sampv; - size_t sampc; auplay_write_h *wh; void *arg; + int16_t *sampv[N_PLAY_QUEUE_BUFFERS]; + size_t sampc; + uint8_t bufferId; SLObjectItf outputMixObject; SLObjectItf bqPlayerObject; @@ -34,7 +39,11 @@ static void auplay_destructor(void *arg) if (st->outputMixObject != NULL) (*st->outputMixObject)->Destroy(st->outputMixObject); - mem_deref(st->sampv); + st->bufferId = 0; + for (int i=0; i<N_PLAY_QUEUE_BUFFERS; i++) { + mem_deref(st->sampv[i]); + } + mem_deref(st->ap); } @@ -43,9 +52,12 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { struct auplay_st *st = context; - st->wh(st->sampv, st->sampc, st->arg); + st->wh(st->sampv[st->bufferId], st->sampc, st->arg); + + (*st->BufferQueue)->Enqueue(bq /*st->BufferQueue*/, + st->sampv[st->bufferId], st->sampc * 2); - (*st->BufferQueue)->Enqueue(bq, st->sampv, st->sampc * 2); + st->bufferId = ( st->bufferId + 1 ) % N_PLAY_QUEUE_BUFFERS; } @@ -148,12 +160,15 @@ int opensles_player_alloc(struct auplay_st **stp, struct auplay *ap, st->wh = wh; st->arg = arg; - st->sampc = prm->srate * prm->ch * prm->ptime / 1000; + st->sampc = prm->srate * prm->ch * PTIME / 1000; - st->sampv = mem_alloc(2 * st->sampc, NULL); - if (!st->sampv) { - err = ENOMEM; - goto out; + st->bufferId = 0; + for (int i=0; i<N_PLAY_QUEUE_BUFFERS; i++) { + st->sampv[i] = mem_zalloc(2 * st->sampc, NULL); + if (!st->sampv[i]) { + err = ENOMEM; + goto out; + } } err = createOutput(st); diff --git a/modules/opensles/recorder.c b/modules/opensles/recorder.c index 6706428..48af5c0 100644 --- a/modules/opensles/recorder.c +++ b/modules/opensles/recorder.c @@ -5,19 +5,22 @@ */ #include <re.h> #include <baresip.h> -#include <pthread.h> +#include <string.h> #include <SLES/OpenSLES.h> #include "SLES/OpenSLES_Android.h" #include "opensles.h" +#define N_REC_QUEUE_BUFFERS 2 +#define PTIME 10 + + struct ausrc_st { struct ausrc *as; /* inheritance */ - int16_t *sampv; - size_t sampc; - uint32_t ptime; - pthread_t thread; - bool run; + + int16_t *sampv[N_REC_QUEUE_BUFFERS]; + size_t sampc; + uint8_t bufferId; ausrc_read_h *rh; void *arg; @@ -31,60 +34,39 @@ static void ausrc_destructor(void *arg) { struct ausrc_st *st = arg; - if (st->run) { - st->run = false; - pthread_join(st->thread, NULL); - } - - if (st->recObject != NULL) - (*st->recObject)->Destroy(st->recObject); - - mem_deref(st->sampv); - mem_deref(st->as); -} - - -static void *record_thread(void *arg) -{ - uint64_t now, ts = tmr_jiffies(); - struct ausrc_st *st = arg; - SLresult r; - - while (st->run) { - - (void)sys_usleep(4000); - - now = tmr_jiffies(); + if (st->recObject != NULL) { + SLuint32 state; - if (ts > now) - continue; -#if 1 - if (now > ts + 100) { - debug("opensles: cpu lagging behind (%u ms)\n", - now - ts); - } -#endif - - r = (*st->recBufferQueue)->Enqueue(st->recBufferQueue, - st->sampv, - st->sampc * 2); - if (r != SL_RESULT_SUCCESS) { - warning("opensles: Enqueue: r = %d\n", r); + if (SL_OBJECT_STATE_UNREALIZED != + (*st->recObject)->GetState(st->recObject,&state)) { + (*st->recObject)->Destroy(st->recObject); } + } - ts += st->ptime; + st->bufferId = 0; + for (int i=0; i<N_REC_QUEUE_BUFFERS; i++) { + mem_deref(st->sampv[i]); } - return NULL; + mem_deref(st->as); } static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { struct ausrc_st *st = context; + (void)bq; - st->rh(st->sampv, st->sampc, st->arg); + st->rh(st->sampv[st->bufferId], st->sampc, st->arg); + + st->bufferId = ( st->bufferId + 1 ) % N_REC_QUEUE_BUFFERS; + + memset(st->sampv[st->bufferId], 0, st->sampc * 2); + + (*st->recBufferQueue)->Enqueue(st->recBufferQueue, + st->sampv[st->bufferId], + st->sampc * 2); } @@ -152,12 +134,12 @@ static int startRecording(struct ausrc_st *st) SL_RECORDSTATE_STOPPED); (*st->recBufferQueue)->Clear(st->recBufferQueue); -#if 0 + st->bufferId = 0; r = (*st->recBufferQueue)->Enqueue(st->recBufferQueue, - st->buf, sizeof(st->buf)); + st->sampv[st->bufferId], + st->sampc * 2); if (SL_RESULT_SUCCESS != r) return ENODEV; -#endif r = (*st->recRecord)->SetRecordState(st->recRecord, SL_RECORDSTATE_RECORDING); @@ -189,13 +171,15 @@ int opensles_recorder_alloc(struct ausrc_st **stp, struct ausrc *as, st->as = mem_ref(as); st->rh = rh; st->arg = arg; - st->ptime = prm->ptime; - st->sampc = prm->srate * prm->ch * prm->ptime / 1000; - st->sampv = mem_alloc(2 * st->sampc, NULL); - if (!st->sampv) { - err = ENOMEM; - goto out; + st->sampc = prm->srate * prm->ch * PTIME / 1000; + st->bufferId = 0; + for (int i=0; i<N_REC_QUEUE_BUFFERS; i++) { + st->sampv[i] = mem_zalloc(2 * st->sampc, NULL); + if (!st->sampv[i]) { + err = ENOMEM; + goto out; + } } err = createAudioRecorder(st, prm); @@ -208,14 +192,6 @@ int opensles_recorder_alloc(struct ausrc_st **stp, struct ausrc *as, goto out; } - st->run = true; - - err = pthread_create(&st->thread, NULL, record_thread, st); - if (err) { - st->run = false; - goto out; - } - out: if (err) |