summaryrefslogtreecommitdiffstats
path: root/tinyDAV/src/audio/tdav_speex_jitterbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyDAV/src/audio/tdav_speex_jitterbuffer.c')
-rwxr-xr-xtinyDAV/src/audio/tdav_speex_jitterbuffer.c453
1 files changed, 225 insertions, 228 deletions
diff --git a/tinyDAV/src/audio/tdav_speex_jitterbuffer.c b/tinyDAV/src/audio/tdav_speex_jitterbuffer.c
index d4639b9..a83f49b 100755
--- a/tinyDAV/src/audio/tdav_speex_jitterbuffer.c
+++ b/tinyDAV/src/audio/tdav_speex_jitterbuffer.c
@@ -36,221 +36,220 @@
#include <speex/speex_jitter.h>
/** Speex JitterBuffer*/
-typedef struct tdav_speex_jitterBuffer_s
-{
- TMEDIA_DECLARE_JITTER_BUFFER;
-
- JitterBuffer* state;
- uint32_t rate;
- uint32_t frame_duration;
- uint32_t channels;
- uint32_t x_data_size; // expected data size
- uint16_t fake_seqnum; // if ptime mismatch then, reassembled pkt will have invalid seqnum
- struct {
- uint8_t* ptr;
- tsk_size_t size;
- tsk_size_t index;
- } buff;
-
- uint64_t num_pkt_in; // Number of incoming pkts since the last reset
- uint64_t num_pkt_miss; // Number of times we got consecutive "JITTER_BUFFER_MISSING" results
- uint64_t num_pkt_miss_max; // Max value for "num_pkt_miss" before reset()ing the jitter buffer
+typedef struct tdav_speex_jitterBuffer_s {
+ TMEDIA_DECLARE_JITTER_BUFFER;
+
+ JitterBuffer* state;
+ uint32_t rate;
+ uint32_t frame_duration;
+ uint32_t channels;
+ uint32_t x_data_size; // expected data size
+ uint16_t fake_seqnum; // if ptime mismatch then, reassembled pkt will have invalid seqnum
+ struct {
+ uint8_t* ptr;
+ tsk_size_t size;
+ tsk_size_t index;
+ } buff;
+
+ uint64_t num_pkt_in; // Number of incoming pkts since the last reset
+ uint64_t num_pkt_miss; // Number of times we got consecutive "JITTER_BUFFER_MISSING" results
+ uint64_t num_pkt_miss_max; // Max value for "num_pkt_miss" before reset()ing the jitter buffer
}
tdav_speex_jitterbuffer_t;
static int tdav_speex_jitterbuffer_set(tmedia_jitterbuffer_t *self, const tmedia_param_t* param)
{
- TSK_DEBUG_ERROR("Not implemented");
- return -2;
+ TSK_DEBUG_ERROR("Not implemented");
+ return -2;
}
static int tdav_speex_jitterbuffer_open(tmedia_jitterbuffer_t* self, uint32_t frame_duration, uint32_t rate, uint32_t channels)
{
- tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
- spx_int32_t tmp;
-
- TSK_DEBUG_INFO("Open speex jb (ptime=%u, rate=%u)", frame_duration, rate);
-
- if (!(jitterbuffer->state = jitter_buffer_init((int)frame_duration))) {
- TSK_DEBUG_ERROR("jitter_buffer_init() failed");
- return -2;
- }
- jitterbuffer->rate = rate;
- jitterbuffer->frame_duration = frame_duration;
- jitterbuffer->channels = channels;
- jitterbuffer->x_data_size = ((frame_duration * jitterbuffer->rate) / 500) << (channels == 2 ? 1 : 0);
-
- jitterbuffer->num_pkt_in = 0;
- jitterbuffer->num_pkt_miss = 0;
- jitterbuffer->num_pkt_miss_max = (1000 / frame_duration) * 2; // 2 seconds missing --> "Houston, we have a problem"
-
- jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MARGIN, &tmp);
- TSK_DEBUG_INFO("Default Jitter buffer margin=%d", tmp);
- jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MAX_LATE_RATE, &tmp);
- TSK_DEBUG_INFO("Default Jitter max late rate=%d", tmp);
-
- if ((tmp = tmedia_defaults_get_jb_margin()) >= 0) {
- jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MARGIN, &tmp);
- TSK_DEBUG_INFO("New Jitter buffer margin=%d", tmp);
- }
- if ((tmp = tmedia_defaults_get_jb_max_late_rate()) >= 0) {
- jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
- TSK_DEBUG_INFO("New Jitter buffer max late rate=%d", tmp);
- }
-
- return 0;
+ tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
+ spx_int32_t tmp;
+
+ TSK_DEBUG_INFO("Open speex jb (ptime=%u, rate=%u)", frame_duration, rate);
+
+ if (!(jitterbuffer->state = jitter_buffer_init((int)frame_duration))) {
+ TSK_DEBUG_ERROR("jitter_buffer_init() failed");
+ return -2;
+ }
+ jitterbuffer->rate = rate;
+ jitterbuffer->frame_duration = frame_duration;
+ jitterbuffer->channels = channels;
+ jitterbuffer->x_data_size = ((frame_duration * jitterbuffer->rate) / 500) << (channels == 2 ? 1 : 0);
+
+ jitterbuffer->num_pkt_in = 0;
+ jitterbuffer->num_pkt_miss = 0;
+ jitterbuffer->num_pkt_miss_max = (1000 / frame_duration) * 2; // 2 seconds missing --> "Houston, we have a problem"
+
+ jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MARGIN, &tmp);
+ TSK_DEBUG_INFO("Default Jitter buffer margin=%d", tmp);
+ jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MAX_LATE_RATE, &tmp);
+ TSK_DEBUG_INFO("Default Jitter max late rate=%d", tmp);
+
+ if ((tmp = tmedia_defaults_get_jb_margin()) >= 0) {
+ jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MARGIN, &tmp);
+ TSK_DEBUG_INFO("New Jitter buffer margin=%d", tmp);
+ }
+ if ((tmp = tmedia_defaults_get_jb_max_late_rate()) >= 0) {
+ jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
+ TSK_DEBUG_INFO("New Jitter buffer max late rate=%d", tmp);
+ }
+
+ return 0;
}
static int tdav_speex_jitterbuffer_tick(tmedia_jitterbuffer_t* self)
{
- tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
- if (!jitterbuffer->state) {
- TSK_DEBUG_ERROR("Invalid state");
- return -1;
- }
- jitter_buffer_tick(jitterbuffer->state);
- return 0;
+ tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
+ if (!jitterbuffer->state) {
+ TSK_DEBUG_ERROR("Invalid state");
+ return -1;
+ }
+ jitter_buffer_tick(jitterbuffer->state);
+ return 0;
}
static int tdav_speex_jitterbuffer_put(tmedia_jitterbuffer_t* self, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr)
{
- tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
- const trtp_rtp_header_t* rtp_hdr;
- JitterBufferPacket jb_packet;
- static uint16_t seq_num = 0;
-
- if (!data || !data_size || !proto_hdr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if (!jb->state) {
- TSK_DEBUG_ERROR("Invalid state");
- return -2;
- }
-
- rtp_hdr = TRTP_RTP_HEADER(proto_hdr);
-
- jb_packet.user_data = 0;
- jb_packet.span = jb->frame_duration;
- jb_packet.len = jb->x_data_size;
-
- if (jb->x_data_size == data_size) { /* ptime match */
- jb_packet.data = data;
- jb_packet.sequence = rtp_hdr->seq_num;
- jb_packet.timestamp = (rtp_hdr->seq_num * jb_packet.span);
- jitter_buffer_put(jb->state, &jb_packet);
- }
- else { /* ptime mismatch */
- tsk_size_t i;
- jb_packet.sequence = 0; // Ignore
- if ((jb->buff.index + data_size) > jb->buff.size) {
- if (!(jb->buff.ptr = tsk_realloc(jb->buff.ptr, (jb->buff.index + data_size)))) {
- jb->buff.size = 0;
- jb->buff.index = 0;
- return 0;
- }
- jb->buff.size = (jb->buff.index + data_size);
- }
-
- memcpy(&jb->buff.ptr[jb->buff.index], data, data_size);
- jb->buff.index += data_size;
-
- if (jb->buff.index >= jb->x_data_size) {
- tsk_size_t copied = 0;
- for (i = 0; (i + jb->x_data_size) <= jb->buff.index; i += jb->x_data_size) {
- jb_packet.data = (char*)&jb->buff.ptr[i];
- jb_packet.timestamp = (++jb->fake_seqnum * jb_packet.span);// reassembled pkt will have fake seqnum
- jitter_buffer_put(jb->state, &jb_packet);
- copied += jb->x_data_size;
- }
- if (copied == jb->buff.index) {
- // all copied
- jb->buff.index = 0;
- }
- else {
- memmove(&jb->buff.ptr[0], &jb->buff.ptr[copied], (jb->buff.index - copied));
- jb->buff.index -= copied;
- }
- }
- }
- ++jb->num_pkt_in;
-
- return 0;
+ tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
+ const trtp_rtp_header_t* rtp_hdr;
+ JitterBufferPacket jb_packet;
+ static uint16_t seq_num = 0;
+
+ if (!data || !data_size || !proto_hdr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if (!jb->state) {
+ TSK_DEBUG_ERROR("Invalid state");
+ return -2;
+ }
+
+ rtp_hdr = TRTP_RTP_HEADER(proto_hdr);
+
+ jb_packet.user_data = 0;
+ jb_packet.span = jb->frame_duration;
+ jb_packet.len = jb->x_data_size;
+
+ if (jb->x_data_size == data_size) { /* ptime match */
+ jb_packet.data = data;
+ jb_packet.sequence = rtp_hdr->seq_num;
+ jb_packet.timestamp = (rtp_hdr->seq_num * jb_packet.span);
+ jitter_buffer_put(jb->state, &jb_packet);
+ }
+ else { /* ptime mismatch */
+ tsk_size_t i;
+ jb_packet.sequence = 0; // Ignore
+ if ((jb->buff.index + data_size) > jb->buff.size) {
+ if (!(jb->buff.ptr = tsk_realloc(jb->buff.ptr, (jb->buff.index + data_size)))) {
+ jb->buff.size = 0;
+ jb->buff.index = 0;
+ return 0;
+ }
+ jb->buff.size = (jb->buff.index + data_size);
+ }
+
+ memcpy(&jb->buff.ptr[jb->buff.index], data, data_size);
+ jb->buff.index += data_size;
+
+ if (jb->buff.index >= jb->x_data_size) {
+ tsk_size_t copied = 0;
+ for (i = 0; (i + jb->x_data_size) <= jb->buff.index; i += jb->x_data_size) {
+ jb_packet.data = (char*)&jb->buff.ptr[i];
+ jb_packet.timestamp = (++jb->fake_seqnum * jb_packet.span);// reassembled pkt will have fake seqnum
+ jitter_buffer_put(jb->state, &jb_packet);
+ copied += jb->x_data_size;
+ }
+ if (copied == jb->buff.index) {
+ // all copied
+ jb->buff.index = 0;
+ }
+ else {
+ memmove(&jb->buff.ptr[0], &jb->buff.ptr[copied], (jb->buff.index - copied));
+ jb->buff.index -= copied;
+ }
+ }
+ }
+ ++jb->num_pkt_in;
+
+ return 0;
}
static tsk_size_t tdav_speex_jitterbuffer_get(tmedia_jitterbuffer_t* self, void* out_data, tsk_size_t out_size)
{
- tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
- JitterBufferPacket jb_packet;
- int ret, miss = 0;
- tsk_size_t ret_size = 0;
-
- if (!out_data || !out_size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
- if (!jb->state) {
- TSK_DEBUG_ERROR("Invalid state");
- return 0;
- }
- if (jb->x_data_size != out_size) { // consumer must request PTIME data
- TSK_DEBUG_WARN("%d not expected as frame size. %u<>%u", out_size, jb->frame_duration, (out_size * 500) / jb->rate);
- return 0;
- }
-
- jb_packet.data = out_data;
- jb_packet.len = (spx_uint32_t)out_size;
-
- if ((ret = jitter_buffer_get(jb->state, &jb_packet, jb->frame_duration/*(out_size * 500)/jb->rate*/, tsk_null)) != JITTER_BUFFER_OK) {
- ++jb->num_pkt_miss;
- switch (ret) {
- case JITTER_BUFFER_MISSING:
- /*TSK_DEBUG_INFO("JITTER_BUFFER_MISSING - %d", ret);*/
- if (jb->num_pkt_miss > jb->num_pkt_miss_max /*too much missing pkts*/ && jb->num_pkt_in > jb->num_pkt_miss_max/*we're really receiving pkts*/) {
- jb->num_pkt_miss = 0;
- self->plugin->reset(self);
- TSK_DEBUG_WARN("Too much missing audio pkts");
- }
- break;
- case JITTER_BUFFER_INSERTION:
- /*TSK_DEBUG_INFO("JITTER_BUFFER_INSERTION - %d", ret);*/
- break;
- default:
- TSK_DEBUG_INFO("jitter_buffer_get() failed - %d", ret);
- break;
- }
- // jitter_buffer_update_delay(jb->state, &jb_packet, NULL);
- //return 0;
- }
- else {
- jb->num_pkt_miss = 0; // reset
- ret_size = jb_packet.len;
- }
- //jitter_buffer_update_delay(jb->state, &jb_packet, NULL);
-
- return ret_size;
+ tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
+ JitterBufferPacket jb_packet;
+ int ret, miss = 0;
+ tsk_size_t ret_size = 0;
+
+ if (!out_data || !out_size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+ if (!jb->state) {
+ TSK_DEBUG_ERROR("Invalid state");
+ return 0;
+ }
+ if (jb->x_data_size != out_size) { // consumer must request PTIME data
+ TSK_DEBUG_WARN("%d not expected as frame size. %u<>%u", out_size, jb->frame_duration, (out_size * 500) / jb->rate);
+ return 0;
+ }
+
+ jb_packet.data = out_data;
+ jb_packet.len = (spx_uint32_t)out_size;
+
+ if ((ret = jitter_buffer_get(jb->state, &jb_packet, jb->frame_duration/*(out_size * 500)/jb->rate*/, tsk_null)) != JITTER_BUFFER_OK) {
+ ++jb->num_pkt_miss;
+ switch (ret) {
+ case JITTER_BUFFER_MISSING:
+ /*TSK_DEBUG_INFO("JITTER_BUFFER_MISSING - %d", ret);*/
+ if (jb->num_pkt_miss > jb->num_pkt_miss_max /*too much missing pkts*/ && jb->num_pkt_in > jb->num_pkt_miss_max/*we're really receiving pkts*/) {
+ jb->num_pkt_miss = 0;
+ self->plugin->reset(self);
+ TSK_DEBUG_WARN("Too much missing audio pkts");
+ }
+ break;
+ case JITTER_BUFFER_INSERTION:
+ /*TSK_DEBUG_INFO("JITTER_BUFFER_INSERTION - %d", ret);*/
+ break;
+ default:
+ TSK_DEBUG_INFO("jitter_buffer_get() failed - %d", ret);
+ break;
+ }
+ // jitter_buffer_update_delay(jb->state, &jb_packet, NULL);
+ //return 0;
+ }
+ else {
+ jb->num_pkt_miss = 0; // reset
+ ret_size = jb_packet.len;
+ }
+ //jitter_buffer_update_delay(jb->state, &jb_packet, NULL);
+
+ return ret_size;
}
static int tdav_speex_jitterbuffer_reset(tmedia_jitterbuffer_t* self)
{
- tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
- if (jb->state) {
- jitter_buffer_reset(jb->state);
- }
- jb->num_pkt_in = 0;
- jb->num_pkt_miss = 0;
- return 0;
+ tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
+ if (jb->state) {
+ jitter_buffer_reset(jb->state);
+ }
+ jb->num_pkt_in = 0;
+ jb->num_pkt_miss = 0;
+ return 0;
}
static int tdav_speex_jitterbuffer_close(tmedia_jitterbuffer_t* self)
{
- tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
- if (jitterbuffer->state) {
- jitter_buffer_destroy(jitterbuffer->state);
- jitterbuffer->state = tsk_null;
- }
- return 0;
+ tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
+ if (jitterbuffer->state) {
+ jitter_buffer_destroy(jitterbuffer->state);
+ jitterbuffer->state = tsk_null;
+ }
+ return 0;
}
@@ -262,56 +261,54 @@ static int tdav_speex_jitterbuffer_close(tmedia_jitterbuffer_t* self)
/* constructor */
static tsk_object_t* tdav_speex_jitterbuffer_ctor(tsk_object_t * self, va_list * app)
{
- tdav_speex_jitterbuffer_t *jitterbuffer = self;
- TSK_DEBUG_INFO("Create SpeexDSP jitter buffer");
- if (jitterbuffer){
- /* init base */
- tmedia_jitterbuffer_init(TMEDIA_JITTER_BUFFER(jitterbuffer));
- /* init self */
- }
- return self;
+ tdav_speex_jitterbuffer_t *jitterbuffer = self;
+ TSK_DEBUG_INFO("Create SpeexDSP jitter buffer");
+ if (jitterbuffer) {
+ /* init base */
+ tmedia_jitterbuffer_init(TMEDIA_JITTER_BUFFER(jitterbuffer));
+ /* init self */
+ }
+ return self;
}
/* destructor */
static tsk_object_t* tdav_speex_jitterbuffer_dtor(tsk_object_t * self)
{
- tdav_speex_jitterbuffer_t *jb = self;
- if (jb){
- /* deinit base */
- tmedia_jitterbuffer_deinit(TMEDIA_JITTER_BUFFER(jb));
- /* deinit self */
- if (jb->state){
- jitter_buffer_destroy(jb->state);
- jb->state = tsk_null;
- }
- TSK_FREE(jb->buff.ptr);
-
- TSK_DEBUG_INFO("*** SpeexDSP jb destroyed ***");
- }
-
- return self;
+ tdav_speex_jitterbuffer_t *jb = self;
+ if (jb) {
+ /* deinit base */
+ tmedia_jitterbuffer_deinit(TMEDIA_JITTER_BUFFER(jb));
+ /* deinit self */
+ if (jb->state) {
+ jitter_buffer_destroy(jb->state);
+ jb->state = tsk_null;
+ }
+ TSK_FREE(jb->buff.ptr);
+
+ TSK_DEBUG_INFO("*** SpeexDSP jb destroyed ***");
+ }
+
+ return self;
}
/* object definition */
-static const tsk_object_def_t tdav_speex_jitterbuffer_def_s =
-{
- sizeof(tdav_speex_jitterbuffer_t),
- tdav_speex_jitterbuffer_ctor,
- tdav_speex_jitterbuffer_dtor,
- tsk_null,
+static const tsk_object_def_t tdav_speex_jitterbuffer_def_s = {
+ sizeof(tdav_speex_jitterbuffer_t),
+ tdav_speex_jitterbuffer_ctor,
+ tdav_speex_jitterbuffer_dtor,
+ tsk_null,
};
/* plugin definition*/
-static const tmedia_jitterbuffer_plugin_def_t tdav_speex_jitterbuffer_plugin_def_s =
-{
- &tdav_speex_jitterbuffer_def_s,
- tmedia_audio,
- "Audio JitterBuffer based on Speex",
-
- tdav_speex_jitterbuffer_set,
- tdav_speex_jitterbuffer_open,
- tdav_speex_jitterbuffer_tick,
- tdav_speex_jitterbuffer_put,
- tdav_speex_jitterbuffer_get,
- tdav_speex_jitterbuffer_reset,
- tdav_speex_jitterbuffer_close,
+static const tmedia_jitterbuffer_plugin_def_t tdav_speex_jitterbuffer_plugin_def_s = {
+ &tdav_speex_jitterbuffer_def_s,
+ tmedia_audio,
+ "Audio JitterBuffer based on Speex",
+
+ tdav_speex_jitterbuffer_set,
+ tdav_speex_jitterbuffer_open,
+ tdav_speex_jitterbuffer_tick,
+ tdav_speex_jitterbuffer_put,
+ tdav_speex_jitterbuffer_get,
+ tdav_speex_jitterbuffer_reset,
+ tdav_speex_jitterbuffer_close,
};
const tmedia_jitterbuffer_plugin_def_t *tdav_speex_jitterbuffer_plugin_def_t = &tdav_speex_jitterbuffer_plugin_def_s;
OpenPOWER on IntegriCloud