summaryrefslogtreecommitdiffstats
path: root/tinyDAV/src/audio/tdav_speakup_jitterbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyDAV/src/audio/tdav_speakup_jitterbuffer.c')
-rwxr-xr-xtinyDAV/src/audio/tdav_speakup_jitterbuffer.c361
1 files changed, 179 insertions, 182 deletions
diff --git a/tinyDAV/src/audio/tdav_speakup_jitterbuffer.c b/tinyDAV/src/audio/tdav_speakup_jitterbuffer.c
index cccc235..0c21e41 100755
--- a/tinyDAV/src/audio/tdav_speakup_jitterbuffer.c
+++ b/tinyDAV/src/audio/tdav_speakup_jitterbuffer.c
@@ -2,19 +2,19 @@
* Copyright (C) 2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -41,7 +41,7 @@
#if TSK_UNDER_WINDOWS
# include <Winsock2.h> // timeval
#elif defined(__SYMBIAN32__)
-# include <_timeval.h>
+# include <_timeval.h>
#else
# include <sys/time.h>
#endif
@@ -52,171 +52,170 @@
static int tdav_speakup_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_speakup_jitterbuffer_open(tmedia_jitterbuffer_t* self, uint32_t frame_duration, uint32_t rate, uint32_t channels)
{
- tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
- if(!jitterbuffer->jbuffer){
- if(!(jitterbuffer->jbuffer = jb_new())){
- TSK_DEBUG_ERROR("Failed to create new buffer");
- return -1;
- }
- jitterbuffer->jcodec = JB_CODEC_OTHER;
- }
- jitterbuffer->ref_timestamp = 0;
- jitterbuffer->frame_duration = frame_duration;
- jitterbuffer->rate = rate;
- jitterbuffer->channels = channels;
- jitterbuffer->_10ms_size_bytes = 160 * (rate/8000);
-
- return 0;
+ tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
+ if(!jitterbuffer->jbuffer) {
+ if(!(jitterbuffer->jbuffer = jb_new())) {
+ TSK_DEBUG_ERROR("Failed to create new buffer");
+ return -1;
+ }
+ jitterbuffer->jcodec = JB_CODEC_OTHER;
+ }
+ jitterbuffer->ref_timestamp = 0;
+ jitterbuffer->frame_duration = frame_duration;
+ jitterbuffer->rate = rate;
+ jitterbuffer->channels = channels;
+ jitterbuffer->_10ms_size_bytes = 160 * (rate/8000);
+
+ return 0;
}
static int tdav_speakup_jitterbuffer_tick(tmedia_jitterbuffer_t* self)
{
- return 0;
+ return 0;
}
static int tdav_speakup_jitterbuffer_put(tmedia_jitterbuffer_t* self, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr)
{
- tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
- const trtp_rtp_header_t* rtp_hdr = (const trtp_rtp_header_t*)proto_hdr;
+ tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
+ const trtp_rtp_header_t* rtp_hdr = (const trtp_rtp_header_t*)proto_hdr;
int i;
long now, ts;
void* _10ms_buf;
- uint8_t* pdata;
-
- if(!self || !data || !data_size || !jitterbuffer->jbuffer || !rtp_hdr){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* synchronize the reference timestamp */
- if(!jitterbuffer->ref_timestamp){
- uint64_t now = tsk_time_now();
- struct timeval tv;
- long ts = (rtp_hdr->timestamp/(jitterbuffer->rate/1000));
- //=> Do not use (see clock_gettime() on linux): tsk_gettimeofday(&tv, tsk_null);
- tv.tv_sec = (long)(now)/1000;
- tv.tv_usec = (long)(now - (tv.tv_sec*1000))*1000;
-
- tv.tv_sec -= (ts / jitterbuffer->rate);
- tv.tv_usec -= (ts % jitterbuffer->rate) * 125;
- if((tv.tv_usec -= (tv.tv_usec % (TDAV_SPEAKUP_10MS * 10000))) <0){
- tv.tv_usec += 1000000;
- tv.tv_sec -= 1;
- }
- jitterbuffer->ref_timestamp = tsk_time_get_ms(&tv);
-
- switch(rtp_hdr->payload_type){
- case 8: /*TMEDIA_CODEC_FORMAT_G711a*/
- case 0: /* TMEDIA_CODEC_FORMAT_G711u */
- jitterbuffer->jcodec = JB_CODEC_G711x;
- break;
- case 18: /* TMEDIA_CODEC_FORMAT_G729 */
- jitterbuffer->jcodec = JB_CODEC_G729A;
- break;
- case 3: /* TMEDIA_CODEC_FORMAT_GSM */
- jitterbuffer->jcodec = JB_CODEC_GSM_EFR;
- break;
-
- default:
- jitterbuffer->jcodec = JB_CODEC_OTHER;
- break;
- }
- }
-
- // split as several 10ms frames
- now = (long) (tsk_time_now()-jitterbuffer->ref_timestamp);
- ts = (long)(rtp_hdr->timestamp/(jitterbuffer->rate/1000));
- pdata = (uint8_t*)data;
- for(i=0; i<(int)(data_size/jitterbuffer->_10ms_size_bytes);i++){
- if((_10ms_buf = tsk_calloc(jitterbuffer->_10ms_size_bytes, 1))){
- memcpy(_10ms_buf, &pdata[i*jitterbuffer->_10ms_size_bytes], jitterbuffer->_10ms_size_bytes);
- jb_put(jitterbuffer->jbuffer, _10ms_buf, JB_TYPE_VOICE, TDAV_SPEAKUP_10MS, ts, now, jitterbuffer->jcodec);
- _10ms_buf = tsk_null;
- }
- ts += TDAV_SPEAKUP_10MS;
- }
-
- return 0;
+ uint8_t* pdata;
+
+ if(!self || !data || !data_size || !jitterbuffer->jbuffer || !rtp_hdr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ /* synchronize the reference timestamp */
+ if(!jitterbuffer->ref_timestamp) {
+ uint64_t now = tsk_time_now();
+ struct timeval tv;
+ long ts = (rtp_hdr->timestamp/(jitterbuffer->rate/1000));
+ //=> Do not use (see clock_gettime() on linux): tsk_gettimeofday(&tv, tsk_null);
+ tv.tv_sec = (long)(now)/1000;
+ tv.tv_usec = (long)(now - (tv.tv_sec*1000))*1000;
+
+ tv.tv_sec -= (ts / jitterbuffer->rate);
+ tv.tv_usec -= (ts % jitterbuffer->rate) * 125;
+ if((tv.tv_usec -= (tv.tv_usec % (TDAV_SPEAKUP_10MS * 10000))) <0) {
+ tv.tv_usec += 1000000;
+ tv.tv_sec -= 1;
+ }
+ jitterbuffer->ref_timestamp = tsk_time_get_ms(&tv);
+
+ switch(rtp_hdr->payload_type) {
+ case 8: /*TMEDIA_CODEC_FORMAT_G711a*/
+ case 0: /* TMEDIA_CODEC_FORMAT_G711u */
+ jitterbuffer->jcodec = JB_CODEC_G711x;
+ break;
+ case 18: /* TMEDIA_CODEC_FORMAT_G729 */
+ jitterbuffer->jcodec = JB_CODEC_G729A;
+ break;
+ case 3: /* TMEDIA_CODEC_FORMAT_GSM */
+ jitterbuffer->jcodec = JB_CODEC_GSM_EFR;
+ break;
+
+ default:
+ jitterbuffer->jcodec = JB_CODEC_OTHER;
+ break;
+ }
+ }
+
+ // split as several 10ms frames
+ now = (long) (tsk_time_now()-jitterbuffer->ref_timestamp);
+ ts = (long)(rtp_hdr->timestamp/(jitterbuffer->rate/1000));
+ pdata = (uint8_t*)data;
+ for(i=0; i<(int)(data_size/jitterbuffer->_10ms_size_bytes); i++) {
+ if((_10ms_buf = tsk_calloc(jitterbuffer->_10ms_size_bytes, 1))) {
+ memcpy(_10ms_buf, &pdata[i*jitterbuffer->_10ms_size_bytes], jitterbuffer->_10ms_size_bytes);
+ jb_put(jitterbuffer->jbuffer, _10ms_buf, JB_TYPE_VOICE, TDAV_SPEAKUP_10MS, ts, now, jitterbuffer->jcodec);
+ _10ms_buf = tsk_null;
+ }
+ ts += TDAV_SPEAKUP_10MS;
+ }
+
+ return 0;
}
static tsk_size_t tdav_speakup_jitterbuffer_get(tmedia_jitterbuffer_t* self, void* out_data, tsk_size_t out_size)
{
- tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
- int jret;
-
- int i, _10ms_count;
- long now;
- short* _10ms_buf = tsk_null;
- uint8_t* pout_data = (uint8_t*)out_data;
-
- if(!out_data || (out_size % jitterbuffer->_10ms_size_bytes)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- _10ms_count = (out_size/jitterbuffer->_10ms_size_bytes);
- now = (long) (tsk_time_now() - jitterbuffer->ref_timestamp);
- for(i=0; i<_10ms_count; i++){
-
- jret = jb_get(jitterbuffer->jbuffer, (void**)&_10ms_buf, now, TDAV_SPEAKUP_10MS);
- switch(jret){
- case JB_INTERP:
- TSK_DEBUG_INFO("JB_INTERP");
- jb_reset_all(jitterbuffer->jbuffer);
- memset(&pout_data[i*jitterbuffer->_10ms_size_bytes], 0, (_10ms_count*jitterbuffer->_10ms_size_bytes)-(i*jitterbuffer->_10ms_size_bytes));
- i = _10ms_count; // for exit
- break;
- case JB_OK:
- case JB_EMPTY:
- case JB_NOFRAME:
- case JB_NOJB:
- {
- if(_10ms_buf && (jret == JB_OK)){
- /* copy data */
- memcpy(&pout_data[i*jitterbuffer->_10ms_size_bytes], _10ms_buf, jitterbuffer->_10ms_size_bytes);
- }
- else{
- /* copy silence */
- memset(&pout_data[i*jitterbuffer->_10ms_size_bytes], 0, jitterbuffer->_10ms_size_bytes);
- }
- }
-
- default:
- break;
- }
- TSK_FREE(_10ms_buf);
- }
-
- return (_10ms_count * jitterbuffer->_10ms_size_bytes);
+ tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
+ int jret;
+
+ int i, _10ms_count;
+ long now;
+ short* _10ms_buf = tsk_null;
+ uint8_t* pout_data = (uint8_t*)out_data;
+
+ if(!out_data || (out_size % jitterbuffer->_10ms_size_bytes)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+
+ _10ms_count = (out_size/jitterbuffer->_10ms_size_bytes);
+ now = (long) (tsk_time_now() - jitterbuffer->ref_timestamp);
+ for(i=0; i<_10ms_count; i++) {
+
+ jret = jb_get(jitterbuffer->jbuffer, (void**)&_10ms_buf, now, TDAV_SPEAKUP_10MS);
+ switch(jret) {
+ case JB_INTERP:
+ TSK_DEBUG_INFO("JB_INTERP");
+ jb_reset_all(jitterbuffer->jbuffer);
+ memset(&pout_data[i*jitterbuffer->_10ms_size_bytes], 0, (_10ms_count*jitterbuffer->_10ms_size_bytes)-(i*jitterbuffer->_10ms_size_bytes));
+ i = _10ms_count; // for exit
+ break;
+ case JB_OK:
+ case JB_EMPTY:
+ case JB_NOFRAME:
+ case JB_NOJB: {
+ if(_10ms_buf && (jret == JB_OK)) {
+ /* copy data */
+ memcpy(&pout_data[i*jitterbuffer->_10ms_size_bytes], _10ms_buf, jitterbuffer->_10ms_size_bytes);
+ }
+ else {
+ /* copy silence */
+ memset(&pout_data[i*jitterbuffer->_10ms_size_bytes], 0, jitterbuffer->_10ms_size_bytes);
+ }
+ }
+
+ default:
+ break;
+ }
+ TSK_FREE(_10ms_buf);
+ }
+
+ return (_10ms_count * jitterbuffer->_10ms_size_bytes);
}
static int tdav_speakup_jitterbuffer_reset(tmedia_jitterbuffer_t* self)
{
- tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
- if(jitterbuffer->jbuffer){
- jb_reset_all(jitterbuffer->jbuffer);
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("invalid parameter");
- return -1;
- }
+ tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
+ if(jitterbuffer->jbuffer) {
+ jb_reset_all(jitterbuffer->jbuffer);
+ return 0;
+ }
+ else {
+ TSK_DEBUG_ERROR("invalid parameter");
+ return -1;
+ }
}
static int tdav_speakup_jitterbuffer_close(tmedia_jitterbuffer_t* self)
{
- tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
- if(jitterbuffer->jbuffer){
- jb_destroy(jitterbuffer->jbuffer);
- jitterbuffer->jbuffer = tsk_null;
- }
- return 0;
+ tdav_speakup_jitterbuffer_t *jitterbuffer = (tdav_speakup_jitterbuffer_t *)self;
+ if(jitterbuffer->jbuffer) {
+ jb_destroy(jitterbuffer->jbuffer);
+ jitterbuffer->jbuffer = tsk_null;
+ }
+ return 0;
}
@@ -228,53 +227,51 @@ static int tdav_speakup_jitterbuffer_close(tmedia_jitterbuffer_t* self)
/* constructor */
static tsk_object_t* tdav_speakup_jitterbuffer_ctor(tsk_object_t * self, va_list * app)
{
- tdav_speakup_jitterbuffer_t *jitterbuffer = self;
- TSK_DEBUG_INFO("Create speekup jitter buffer");
- if(jitterbuffer){
- /* init base */
- tmedia_jitterbuffer_init(TMEDIA_JITTER_BUFFER(jitterbuffer));
- /* init self */
- }
- return self;
+ tdav_speakup_jitterbuffer_t *jitterbuffer = self;
+ TSK_DEBUG_INFO("Create speekup jitter buffer");
+ if(jitterbuffer) {
+ /* init base */
+ tmedia_jitterbuffer_init(TMEDIA_JITTER_BUFFER(jitterbuffer));
+ /* init self */
+ }
+ return self;
}
/* destructor */
static tsk_object_t* tdav_speakup_jitterbuffer_dtor(tsk_object_t * self)
-{
- tdav_speakup_jitterbuffer_t *jitterbuffer = self;
- if(jitterbuffer){
- /* deinit base */
- tmedia_jitterbuffer_deinit(TMEDIA_JITTER_BUFFER(jitterbuffer));
- /* deinit self */
- if(jitterbuffer->jbuffer){
- jb_destroy(jitterbuffer->jbuffer);
- jitterbuffer->jbuffer = tsk_null;
- }
- }
-
- return self;
+{
+ tdav_speakup_jitterbuffer_t *jitterbuffer = self;
+ if(jitterbuffer) {
+ /* deinit base */
+ tmedia_jitterbuffer_deinit(TMEDIA_JITTER_BUFFER(jitterbuffer));
+ /* deinit self */
+ if(jitterbuffer->jbuffer) {
+ jb_destroy(jitterbuffer->jbuffer);
+ jitterbuffer->jbuffer = tsk_null;
+ }
+ }
+
+ return self;
}
/* object definition */
-static const tsk_object_def_t tdav_speakup_jitterbuffer_def_s =
-{
- sizeof(tdav_speakup_jitterbuffer_t),
- tdav_speakup_jitterbuffer_ctor,
- tdav_speakup_jitterbuffer_dtor,
- tsk_null,
+static const tsk_object_def_t tdav_speakup_jitterbuffer_def_s = {
+ sizeof(tdav_speakup_jitterbuffer_t),
+ tdav_speakup_jitterbuffer_ctor,
+ tdav_speakup_jitterbuffer_dtor,
+ tsk_null,
};
/* plugin definition*/
-static const tmedia_jitterbuffer_plugin_def_t tdav_speakup_jitterbuffer_plugin_def_s =
-{
- &tdav_speakup_jitterbuffer_def_s,
- tmedia_audio,
- "Audio/video JitterBuffer based on Speakup",
-
- tdav_speakup_jitterbuffer_set,
- tdav_speakup_jitterbuffer_open,
- tdav_speakup_jitterbuffer_tick,
- tdav_speakup_jitterbuffer_put,
- tdav_speakup_jitterbuffer_get,
- tdav_speakup_jitterbuffer_reset,
- tdav_speakup_jitterbuffer_close,
+static const tmedia_jitterbuffer_plugin_def_t tdav_speakup_jitterbuffer_plugin_def_s = {
+ &tdav_speakup_jitterbuffer_def_s,
+ tmedia_audio,
+ "Audio/video JitterBuffer based on Speakup",
+
+ tdav_speakup_jitterbuffer_set,
+ tdav_speakup_jitterbuffer_open,
+ tdav_speakup_jitterbuffer_tick,
+ tdav_speakup_jitterbuffer_put,
+ tdav_speakup_jitterbuffer_get,
+ tdav_speakup_jitterbuffer_reset,
+ tdav_speakup_jitterbuffer_close,
};
const tmedia_jitterbuffer_plugin_def_t *tdav_speakup_jitterbuffer_plugin_def_t = &tdav_speakup_jitterbuffer_plugin_def_s;
OpenPOWER on IntegriCloud