123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #include "precompile.h"
- #include "audiocache.h"
- #include "audiocontext.h"
- #include "audiolog.h"
- static void process_frame(void *self)
- {
- apr_status_t status;
- audiocache_t *cache = CONTAINING_RECORD(self, audiocache_t, driver_base);
- if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_WRITE) {
- if (cache->pending_write.size != SUGGEST_FRAME_SIZE && cache->pending_write.size > 0) {
- status = cache->stream_base.vtbl->write_frame(cache->stream_base.downstream,
- &cache->pending_write);
- if (status != APR_SUCCESS) {
- audio_log_v(AUDIO_LOG_LEVEL_DEBUG,"audiostream write_frame failed, status = %d", status);
- }
- }
- }
- if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_READ) {
- cache->pending_read.size = SUGGEST_FRAME_SIZE;
- status = cache->stream_base.vtbl->read_frame(cache->stream_base.downstream,
- &cache->pending_read);
- if (status != APR_SUCCESS) {
- audio_log_v(AUDIO_LOG_LEVEL_DEBUG,"audiostream read_frame failed");
- }
- }
- }
- static apr_status_t read_frame(void *self, audioframe_t *frame)
- {
- apr_status_t status;
- audiocache_t *cache = CONTAINING_RECORD(self, audiocache_t, stream_base);
- if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_READ) {
- status = audioframe_copy(frame, &cache->pending_read);
- if (status != APR_SUCCESS) {
- audio_log_v(AUDIO_LOG_LEVEL_ERROR, "audiostream_cached_read_frame failed, frm->size little than stream pending frame");
- }
- return status;
- }
- return APR_EGENERAL;
- }
- static apr_status_t write_frame(void *self, const audioframe_t *frame)
- {
- apr_status_t status;
- audiocache_t *cache = CONTAINING_RECORD(self, audiocache_t, stream_base);
- if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_WRITE) {
- cache->pending_write.size = SUGGEST_FRAME_SIZE;
- status = audioframe_copy(&cache->pending_write, frame);
- if (status != APR_SUCCESS) {
- audio_log_v(AUDIO_LOG_LEVEL_ERROR, "audiostream_cached_write_frame failed, frm->size larger than stream pending frame");
- return status;
- }
- }
- return APR_EGENERAL;
- }
- typedef struct audiostream_read_only {
- audiostream_t base;
- audiocache_t *cache;
- }audiostream_read_only;
- typedef struct audiostream_write_only {
- audiostream_t base;
- audiocache_t *cache;
- }audiostream_write_only;
- static apr_status_t istream_read_frame(void *self, audioframe_t *frame)
- {
- audiostream_read_only *ro = (audiostream_read_only *)self;
- audiocache_t *cache = ro->cache;
- return read_frame(&cache->stream_base, frame);
- }
- static apr_status_t ostream_write_frame(void *self, const audioframe_t *frame)
- {
- audiostream_write_only *wo = (audiostream_write_only *)self;
- audiocache_t *cache = wo->cache;
- return write_frame(&cache->stream_base, frame);
- }
- static audiodriver_vtbl_t g_driver_vtbl = {
- &process_frame,
- };
- static audiostream_vtbl_t g_stream_vtbl = {
- &read_frame,
- &write_frame,
- };
- static audiostream_vtbl_t g_istream_vtbl = {
- &istream_read_frame,
- NULL,
- };
- static audiostream_vtbl_t g_ostream_vtbl = {
- NULL,
- &ostream_write_frame,
- };
- apr_status_t audiocache_create(apr_pool_t *pool,
- audioengine_t *engine,
- int istream_cnt,
- int ostream_cnt,
- audiocache_t **p_cache)
- {
- audiocache_t *cache;
- int i;
- cache = apr_palloc(pool, sizeof(audiocache_t));
- cache->pending_read.size = SUGGEST_FRAME_SIZE;
- cache->pending_read.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
- cache->pending_read.dtmf = 0;
- cache->pending_write.size = SUGGEST_FRAME_SIZE;
- cache->pending_write.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
- cache->pending_write.dtmf = 0;
- audiostream_init(engine, &g_stream_vtbl, &cache->stream_base);
- audiodriver_init(engine, &g_driver_vtbl, &cache->driver_base);
- cache->arr_istream = apr_array_make(pool, istream_cnt, sizeof(audiostream_read_only*));
- for (i = 0; i < istream_cnt; ++i) {
- audiostream_read_only *ro = apr_palloc(pool, sizeof(audiostream_read_only));
- audiostream_init(engine, &g_istream_vtbl, &ro->base);
- ro->base.direction = STREAM_DIR_READ;
- ro->cache = cache;
- APR_ARRAY_PUSH(cache->arr_istream, audiostream_read_only*) = ro;
- }
- cache->arr_ostream = apr_array_make(pool, ostream_cnt, sizeof(audiostream_write_only*));
- for (i = 0; i < ostream_cnt; ++i) {
- audiostream_write_only *wo = apr_palloc(pool, sizeof(audiostream_write_only));
- audiostream_init(engine, &g_ostream_vtbl, &wo->base);
- wo->base.direction = STREAM_DIR_WRITE;
- APR_ARRAY_PUSH(cache->arr_ostream, audiostream_write_only*) = wo;
- }
- *p_cache = cache;
- return APR_SUCCESS;
- }
- void audiocache_destroy(audiocache_t *cache)
- {
-
- }
- audiostream_t* audiocache_get_istream(audiocache_t *cache, int idx)
- {
- audiostream_read_only *ro = APR_ARRAY_IDX(cache->arr_istream, idx, audiostream_read_only *);
- return &ro->base;
- }
- audiostream_t* audiocache_get_ostream(audiocache_t *cache, int idx)
- {
- audiostream_write_only *wo = APR_ARRAY_IDX(cache->arr_ostream, idx, audiostream_write_only *);
- return &wo->base;
- }
|