Updated libs
This commit is contained in:
parent
42f4e4a243
commit
e8a91e12f9
|
@ -1508,7 +1508,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len)
|
|||
g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
|
||||
else
|
||||
g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
|
||||
osmo_cc_rtp_send(call->codec, data, len, 1, len);
|
||||
osmo_cc_rtp_send(call->codec, data, len, 0, 1, len);
|
||||
free(data);
|
||||
|
||||
/* mix audio for (hold) remote interface and forward */
|
||||
|
@ -1525,7 +1525,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len)
|
|||
g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
|
||||
else
|
||||
g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
|
||||
osmo_cc_rtp_send(other->codec, data, len, 1, len);
|
||||
osmo_cc_rtp_send(other->codec, data, len, 0, 1, len);
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
@ -1537,7 +1537,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len)
|
|||
if (call->bridge_enabled)
|
||||
return;
|
||||
|
||||
osmo_cc_rtp_send(call->codec, data, len, 1, len);
|
||||
osmo_cc_rtp_send(call->codec, data, len, 0, 1, len);
|
||||
}
|
||||
|
||||
/* receive audio and control from B-channel, transmit data from jitter buffer accoring to received length */
|
||||
|
|
|
@ -292,11 +292,11 @@ static void ph_socket_rx_msg(ph_socket_t *s, int channel, uint8_t prim, uint8_t
|
|||
case PH_PRIM_CTRL_IND:
|
||||
if (length >= 1) {
|
||||
switch (data[0]) {
|
||||
case PH_CTRL_ENABLE:
|
||||
case PH_CTRL_UNBLOCK:
|
||||
printk(KERN_DEBUG "PH-SOCKET Interface available\n");
|
||||
drv->enabled = 1;
|
||||
break;
|
||||
case PH_CTRL_DISABLE:
|
||||
case PH_CTRL_BLOCK:
|
||||
printk(KERN_DEBUG "PH-SOCKET Interface unavailable\n");
|
||||
drv->enabled = 0;
|
||||
if (drv->activated) {
|
||||
|
|
|
@ -57,6 +57,7 @@ struct debug_cat {
|
|||
{ "jollycom", "\033[1;34m" },
|
||||
{ "eurosignal", "\033[1;34m" },
|
||||
{ "pocsag", "\033[1;34m" },
|
||||
{ "golay", "\033[1;34m" },
|
||||
{ "5-ton-folge", "\033[1;34m" },
|
||||
{ "frame", "\033[0;36m" },
|
||||
{ "call", "\033[0;37m" },
|
||||
|
|
|
@ -19,43 +19,44 @@
|
|||
#define DJOLLY 12
|
||||
#define DEURO 13
|
||||
#define DPOCSAG 14
|
||||
#define DFUENF 15
|
||||
#define DFRAME 16
|
||||
#define DCALL 17
|
||||
#define DCC 18
|
||||
#define DDB 19
|
||||
#define DTRANS 20
|
||||
#define DDMS 21
|
||||
#define DSMS 22
|
||||
#define DSDR 23
|
||||
#define DUHD 24
|
||||
#define DSOAPY 25
|
||||
#define DWAVE 26
|
||||
#define DRADIO 27
|
||||
#define DAM791X 28
|
||||
#define DUART 29
|
||||
#define DDEVICE 30
|
||||
#define DDATENKLO 31
|
||||
#define DZEIT 32
|
||||
#define DSIM1 33
|
||||
#define DSIM2 34
|
||||
#define DSIMI 35
|
||||
#define DSIM7 36
|
||||
#define DMTP2 37
|
||||
#define DMTP3 38
|
||||
#define DMUP 39
|
||||
#define DROUTER 40
|
||||
#define DSTDERR 41
|
||||
#define DSS5 42
|
||||
#define DISDN 43
|
||||
#define DMISDN 44
|
||||
#define DDSS1 45
|
||||
#define DSIP 46
|
||||
#define DTEL 47
|
||||
#define DUK0 48
|
||||
#define DPH 49
|
||||
#define DDCF77 50
|
||||
#define DJITTER 51
|
||||
#define DGOLAY 15
|
||||
#define DFUENF 16
|
||||
#define DFRAME 17
|
||||
#define DCALL 18
|
||||
#define DCC 19
|
||||
#define DDB 20
|
||||
#define DTRANS 21
|
||||
#define DDMS 22
|
||||
#define DSMS 23
|
||||
#define DSDR 24
|
||||
#define DUHD 25
|
||||
#define DSOAPY 26
|
||||
#define DWAVE 27
|
||||
#define DRADIO 28
|
||||
#define DAM791X 29
|
||||
#define DUART 30
|
||||
#define DDEVICE 31
|
||||
#define DDATENKLO 32
|
||||
#define DZEIT 33
|
||||
#define DSIM1 34
|
||||
#define DSIM2 35
|
||||
#define DSIMI 36
|
||||
#define DSIM7 37
|
||||
#define DMTP2 38
|
||||
#define DMTP3 39
|
||||
#define DMUP 40
|
||||
#define DROUTER 41
|
||||
#define DSTDERR 42
|
||||
#define DSS5 43
|
||||
#define DISDN 44
|
||||
#define DMISDN 45
|
||||
#define DDSS1 46
|
||||
#define DSIP 47
|
||||
#define DTEL 48
|
||||
#define DUK0 49
|
||||
#define DPH 50
|
||||
#define DDCF77 51
|
||||
#define DJITTER 52
|
||||
//NOTE: increment mask array, if 127 is exceeded
|
||||
|
||||
void lock_debug(void);
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
*
|
||||
* Packets with the same sequence are dropped.
|
||||
*
|
||||
* Early packts that exceed maximum jitter window size cause jitter
|
||||
* window to shift into the future.
|
||||
*
|
||||
* Late packets cause jitter window to shift into the past (allowing more
|
||||
* delay). Minimum jitter window size is added also, to prevent subsequent
|
||||
* packets from beeing late too.
|
||||
*
|
||||
* Early packts that exceed maximum jitter window size cause jitter
|
||||
* window to shift into the future.
|
||||
*
|
||||
* If no sequence is provided (autosequence), the sequence number is generated
|
||||
* by a counter. Also the timestamp is generated by counting the length of each
|
||||
* frame.
|
||||
|
@ -51,16 +51,17 @@
|
|||
*
|
||||
* Missing packets are interpolated by repeating last 20ms of audio (optional)
|
||||
* or by inserting zeroes (sample size > 1 byte) or by inserting 0xff (sample
|
||||
* size = 1).
|
||||
* size = 1). In case of repeating audio, the number of turns are limited until
|
||||
* buffer is reset to silence, if no frames are received for a certain time.
|
||||
*
|
||||
* Optionally the constant delay will be measured continuously and lowered to
|
||||
* minimum window size. (adaptive jitter buffer window)
|
||||
* Optionally the constant delay will be measured continuously and lowered if
|
||||
* greater than minimum window size. (adaptive jitter buffer size)
|
||||
*
|
||||
* Note that the delay is measured with time stamp of frame, no matter what
|
||||
* the length is. Length is an extra delay, but not considered here.
|
||||
*
|
||||
*
|
||||
* Unocking:
|
||||
* Unlocking:
|
||||
*
|
||||
* If the buffer is created or reset, the buffer is locked, so no packets are
|
||||
* stored. When the playout routine is called, the buffer is unlocked. This
|
||||
|
@ -80,8 +81,9 @@
|
|||
#include "jitter.h"
|
||||
|
||||
#define INITIAL_DELAY_INTERVAL 0.5
|
||||
#define REPEAT_DELAY_INTERVAL 2.0
|
||||
#define REPEAT_DELAY_INTERVAL 3.0
|
||||
#define EXTRA_BUFFER 0.020 // 20 ms
|
||||
#define EXTRA_TIMEOUT 0.500 // maximum time to repeat extrapolation buffer
|
||||
|
||||
/* uncomment to enable heavy debugging */
|
||||
//#define HEAVY_DEBUG
|
||||
|
@ -98,7 +100,6 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_
|
|||
jb->target_window_size = (int)(samplerate * target_window_duration);
|
||||
jb->max_window_size = (int)(samplerate * max_window_duration);
|
||||
jb->window_flags = window_flags;
|
||||
jb->delay_value = -1;
|
||||
|
||||
jb->extra_size = (int)(EXTRA_BUFFER * samplerate);
|
||||
jb->extra_samples = calloc(sample_size, jb->extra_size);
|
||||
|
@ -107,7 +108,7 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_
|
|||
rc = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
jb->extra_timeout_max = (int)ceil(EXTRA_TIMEOUT / EXTRA_BUFFER);
|
||||
|
||||
/* optionally give a string to be show with the debug */
|
||||
if (name && *name)
|
||||
|
@ -117,7 +118,7 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_
|
|||
|
||||
jitter_reset(jb);
|
||||
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%sCreated jitter buffer.\n", jb->name);
|
||||
PDEBUG(DJITTER, DEBUG_INFO, "%sCreated jitter buffer. (samplerate=%.0f, target_window=%.0fms, max_window=%.0fms, flag:latency=%s flag:repeat=%s)\n", jb->name, samplerate, target_window_duration * 1000.0, max_window_duration * 1000.0, (window_flags & JITTER_FLAG_LATENCY) ? "true" : "false", (window_flags & JITTER_FLAG_REPEAT) ? "true" : "false");
|
||||
|
||||
error:
|
||||
if (rc)
|
||||
|
@ -125,15 +126,20 @@ error:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void clear_extra_buffer(jitter_t *jb)
|
||||
{
|
||||
if (jb->sample_size == 1)
|
||||
memset(jb->extra_samples, 0xff, jb->sample_size * jb->extra_size);
|
||||
else
|
||||
memset(jb->extra_samples, 0, jb->sample_size * jb->extra_size);
|
||||
}
|
||||
|
||||
/* reset jitter buffer */
|
||||
void jitter_reset(jitter_t *jb)
|
||||
{
|
||||
jitter_frame_t *jf, *temp;
|
||||
|
||||
if (!jb->window_valid)
|
||||
return;
|
||||
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%sReset jitter buffer.\n", jb->name);
|
||||
PDEBUG(DJITTER, DEBUG_INFO, "%sReset jitter buffer.\n", jb->name);
|
||||
|
||||
/* jitter buffer locked */
|
||||
jb->unlocked = 0;
|
||||
|
@ -151,20 +157,22 @@ void jitter_reset(jitter_t *jb)
|
|||
jb->frame_list = NULL;
|
||||
|
||||
/* clear extrapolation buffer */
|
||||
if (jb->extra_samples) {
|
||||
if (jb->sample_size == 1)
|
||||
memset(jb->extra_samples, 0xff, jb->sample_size * jb->extra_size);
|
||||
else
|
||||
memset(jb->extra_samples, 0, jb->sample_size * jb->extra_size);
|
||||
}
|
||||
if (jb->extra_samples)
|
||||
clear_extra_buffer(jb);
|
||||
jb->extra_index = 0;
|
||||
jb->extra_timeout_count = jb->extra_timeout_max; /* no data in buffer yet, so we set timeout condition */
|
||||
|
||||
/* delay measurement and reduction */
|
||||
jb->delay_counter = 0.0;
|
||||
jb->delay_interval = INITIAL_DELAY_INTERVAL;
|
||||
jb->min_delay_value = -1;
|
||||
}
|
||||
|
||||
void jitter_destroy(jitter_t *jb)
|
||||
{
|
||||
jitter_reset(jb);
|
||||
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%sDestroying jitter buffer.\n", jb->name);
|
||||
PDEBUG(DJITTER, DEBUG_INFO, "%sDestroying jitter buffer.\n", jb->name);
|
||||
|
||||
if (jb->extra_samples) {
|
||||
free(jb->extra_samples);
|
||||
|
@ -208,6 +216,25 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint
|
|||
jb->next_timestamp = timestamp + length;
|
||||
}
|
||||
|
||||
/* first packet (with this ssrc) sets window size to target_window_size */
|
||||
if (!jb->window_valid || jb->window_ssrc != ssrc) {
|
||||
if (!jb->window_valid)
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Initial frame after init or reset.\n", jb->name);
|
||||
else
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s SSRC changed.\n", jb->name);
|
||||
// NOTE: Reset must be called before finding the frame location below, because there will be no frame in list anymore!
|
||||
jitter_reset(jb);
|
||||
jb->unlocked = 1;
|
||||
/* when using dynamic jitter buffer, we use half of the target delay */
|
||||
if ((jb->window_flags & JITTER_FLAG_LATENCY)) {
|
||||
jb->window_timestamp = timestamp - (uint32_t)jb->target_window_size / 2;
|
||||
} else {
|
||||
jb->window_timestamp = timestamp - (uint32_t)jb->target_window_size;
|
||||
}
|
||||
jb->window_valid = 1;
|
||||
jb->window_ssrc = ssrc;
|
||||
}
|
||||
|
||||
/* find location where to put frame into the list, depending on sequence number */
|
||||
jfp = &jb->frame_list;
|
||||
while(*jfp) {
|
||||
|
@ -223,37 +250,25 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint
|
|||
jfp = &((*jfp)->next);
|
||||
}
|
||||
|
||||
/* first packet (with this ssrc) sets window size to target_window_size */
|
||||
if (!jb->window_valid || jb->window_ssrc != ssrc) {
|
||||
if (!jb->window_valid)
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Initial frame after init or reset.\n", jb->name);
|
||||
else
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s SSRC changed.\n", jb->name);
|
||||
jitter_reset(jb);
|
||||
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
|
||||
jb->window_valid = 1;
|
||||
jb->window_ssrc = ssrc;
|
||||
jb->delay_counter = 0.0;
|
||||
jb->delay_interval = INITIAL_DELAY_INTERVAL;
|
||||
jb->delay_value = -1;
|
||||
}
|
||||
|
||||
offset_timestamp = timestamp - jb->window_timestamp;
|
||||
#ifdef HEAVY_DEBUG
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%sFrame has offset of %.0fms in jitter buffer.\n", jb->name, (double)offset_timestamp * jb->sample_duration * 1000.0);
|
||||
#endif
|
||||
|
||||
/* measure delay */
|
||||
if (offset_timestamp > jb->delay_value)
|
||||
jb->delay_value = offset_timestamp;
|
||||
if (jb->min_delay_value < 0 || offset_timestamp < jb->min_delay_value)
|
||||
jb->min_delay_value = offset_timestamp;
|
||||
|
||||
/* if frame is too early (delay ceases), shift window to the future */
|
||||
if (offset_timestamp > jb->max_window_size) {
|
||||
if ((jb->window_flags & JITTER_FLAG_LATENCY)) {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, and add target window size. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size);
|
||||
/* shift window so frame fits to the start of window + target delay */
|
||||
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
|
||||
} else {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size);
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, to make the frame fit to the end. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size);
|
||||
/* shift window so it fits to the end of window */
|
||||
jb->window_timestamp = timestamp - jb->max_window_size;
|
||||
} else {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, to make the frame fit to the target delay. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size);
|
||||
/* shift window so frame fits to the start of window + target delay */
|
||||
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,12 +276,12 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint
|
|||
if (offset_timestamp < 0) {
|
||||
if ((jb->window_flags & JITTER_FLAG_LATENCY)) {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past, and add target window size. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp);
|
||||
/* shift window so frame fits to the start of window + half of target delay */
|
||||
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size) / 2;
|
||||
} else {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past, and add half target window size. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp);
|
||||
/* shift window so frame fits to the start of window + target delay */
|
||||
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
|
||||
} else {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp);
|
||||
/* shift window so frame fits to the start of window */
|
||||
jb->window_timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,18 +317,21 @@ void jitter_load(jitter_t *jb, void *samples, int length)
|
|||
/* now unlock jitter buffer */
|
||||
jb->unlocked = 1;
|
||||
|
||||
/* reduce delay */
|
||||
jb->delay_counter += jb->sample_duration * (double)length;
|
||||
if (jb->delay_counter >= jb->delay_interval) {
|
||||
if (jb->delay_value >= 0)
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Statistics: target_delay=%.0fms max_delay=%.0fms current_delay=%.0fms\n", jb->name, (double)jb->target_window_size * jb->sample_duration * 1000.0, (double)jb->max_window_size * jb->sample_duration * 1000.0, (double)jb->delay_value * jb->sample_duration * 1000.0);
|
||||
/* delay reduction, if greater than target jitter window size */
|
||||
if ((jb->window_flags & JITTER_FLAG_LATENCY) && jb->delay_value > jb->target_window_size) {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Reducing current delay of %.0fms that is greater than target jitter window size of %.0fms.\n", jb->name, (double)jb->delay_value * jb->sample_duration * 1000.0, (double)jb->target_window_size * jb->sample_duration * 1000.0);
|
||||
jb->window_timestamp += (uint32_t)(jb->delay_value - jb->target_window_size);
|
||||
if (jb->min_delay_value >= 0)
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Statistics: target_window_delay=%.0fms max_window_delay=%.0fms current min_delay=%.0fms\n", jb->name, (double)jb->target_window_size * jb->sample_duration * 1000.0, (double)jb->max_window_size * jb->sample_duration * 1000.0, (double)jb->min_delay_value * jb->sample_duration * 1000.0);
|
||||
/* delay reduction, if maximum delay is greater than target jitter window size */
|
||||
if ((jb->window_flags & JITTER_FLAG_LATENCY) && jb->min_delay_value > jb->target_window_size) {
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Reducing current minimum delay of %.0fms, because maximum delay is greater than target window size of %.0fms.\n", jb->name, (double)jb->min_delay_value * jb->sample_duration * 1000.0, (double)jb->target_window_size * jb->sample_duration * 1000.0);
|
||||
/* only reduce delay to half of the target window size */
|
||||
jb->window_timestamp += jb->min_delay_value - jb->target_window_size / 2;
|
||||
|
||||
}
|
||||
jb->delay_counter -= jb->delay_interval;
|
||||
jb->delay_interval = REPEAT_DELAY_INTERVAL;
|
||||
jb->delay_value = -1;
|
||||
jb->min_delay_value = -1;
|
||||
}
|
||||
|
||||
/* process all frames until output buffer is loaded */
|
||||
|
@ -342,8 +360,18 @@ void jitter_load(jitter_t *jb, void *samples, int length)
|
|||
count2 = jb->extra_size - jb->extra_index;
|
||||
memcpy(samples, (uint8_t *)jb->extra_samples + jb->extra_index * jb->sample_size, count2 * jb->sample_size);
|
||||
jb->extra_index += count2;
|
||||
if (jb->extra_index == jb->extra_size)
|
||||
if (jb->extra_index == jb->extra_size) {
|
||||
jb->extra_index = 0;
|
||||
if ((jb->window_flags & JITTER_FLAG_REPEAT) && jb->extra_timeout_count < jb->extra_timeout_max) {
|
||||
jb->extra_timeout_count++;
|
||||
if (jb->extra_timeout_count == jb->extra_timeout_max) {
|
||||
#ifdef HEAVY_DEBUG
|
||||
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Repeated jitter buffer enough, clearing to silence.\n", jb->name);
|
||||
#endif
|
||||
clear_extra_buffer(jb);
|
||||
}
|
||||
}
|
||||
}
|
||||
samples = (uint8_t *)samples + count2 * jb->sample_size;
|
||||
length -= count2;
|
||||
jb->window_timestamp += count2;
|
||||
|
@ -360,8 +388,8 @@ void jitter_load(jitter_t *jb, void *samples, int length)
|
|||
count = length;
|
||||
if (jf->length - index < count)
|
||||
count = jf->length - index;
|
||||
/* if extrapolation is used, limit count to what we can store into buffer */
|
||||
if (jb->extra_samples && jb->extra_size - jb->extra_index < count)
|
||||
/* if extrapolation is to be written, limit count to what we can store into buffer */
|
||||
if ((jb->window_flags & JITTER_FLAG_REPEAT) && jb->extra_size - jb->extra_index < count)
|
||||
count = jb->extra_size - jb->extra_index;
|
||||
/* copy samples from packet to play out, increment sample pointer and decrement length */
|
||||
#ifdef HEAVY_DEBUG
|
||||
|
@ -376,6 +404,7 @@ void jitter_load(jitter_t *jb, void *samples, int length)
|
|||
jb->extra_index += count;
|
||||
if (jb->extra_index == jb->extra_size)
|
||||
jb->extra_index = 0;
|
||||
jb->extra_timeout_count = 0; /* now we have new data, we reset timeout condition */
|
||||
}
|
||||
/* increment time stamp */
|
||||
jb->window_timestamp += count;
|
||||
|
|
|
@ -39,12 +39,14 @@ typedef struct jitter {
|
|||
/* reduction of delay */
|
||||
double delay_interval;
|
||||
double delay_counter;
|
||||
int32_t delay_value;
|
||||
int32_t min_delay_value;
|
||||
|
||||
/* extrapolation */
|
||||
int extra_size;
|
||||
int extra_index;
|
||||
void *extra_samples;
|
||||
int extra_timeout_max;
|
||||
int extra_timeout_count;
|
||||
|
||||
/* list of frames */
|
||||
jitter_frame_t *frame_list;
|
||||
|
|
|
@ -568,6 +568,18 @@ static void notify_ind(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
|
|||
forward_to_ul(call, msg);
|
||||
}
|
||||
|
||||
static void update_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
|
||||
{
|
||||
/* to lower layer */
|
||||
forward_to_ll(call, msg);
|
||||
}
|
||||
|
||||
static void update_cnf(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
|
||||
{
|
||||
/* to upper layer */
|
||||
forward_to_ul(call, msg);
|
||||
}
|
||||
|
||||
static void disc_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
|
||||
{
|
||||
/* change state */
|
||||
|
@ -853,6 +865,10 @@ static struct statemachine {
|
|||
OSMO_CC_MSG_INFO_IND, info_ind},
|
||||
{SBIT(OSMO_CC_STATE_ACTIVE),
|
||||
OSMO_CC_MSG_INFO_REQ, info_req},
|
||||
{SBIT(OSMO_CC_STATE_ACTIVE),
|
||||
OSMO_CC_MSG_UPDATE_REQ, update_req},
|
||||
{SBIT(OSMO_CC_STATE_ACTIVE),
|
||||
OSMO_CC_MSG_UPDATE_CNF, update_cnf},
|
||||
|
||||
/* call release */
|
||||
{SBIT(OSMO_CC_STATE_INIT_OUT) | SBIT(OSMO_CC_STATE_INIT_IN) |
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "endpoint.h"
|
||||
#include "helper.h"
|
||||
|
||||
osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug)
|
||||
osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug)
|
||||
{
|
||||
osmo_cc_session_t *session;
|
||||
osmo_cc_session_media_t *media;
|
||||
|
@ -52,7 +52,7 @@ osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, vo
|
|||
return session;
|
||||
}
|
||||
|
||||
const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec)
|
||||
const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec)
|
||||
{
|
||||
char offer_sdp[65536];
|
||||
const char *accept_sdp;
|
||||
|
|
|
@ -7,7 +7,7 @@ struct osmo_cc_helper_audio_codecs {
|
|||
void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len);
|
||||
};
|
||||
|
||||
osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug);
|
||||
const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec);
|
||||
osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug);
|
||||
const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec);
|
||||
int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p);
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ enum osmo_cc_msg_type {
|
|||
OSMO_CC_MSG_NOTIFY_IND = 0x85,
|
||||
OSMO_CC_MSG_INFO_REQ = 0x88,
|
||||
OSMO_CC_MSG_INFO_IND = 0x89,
|
||||
OSMO_CC_MSG_UPDATE_REQ = 0x91,
|
||||
OSMO_CC_MSG_UPDATE_CNF = 0x93,
|
||||
OSMO_CC_MSG_ATTACH_REQ = 0xf8,
|
||||
OSMO_CC_MSG_ATTACH_IND = 0xf9,
|
||||
OSMO_CC_MSG_ATTACH_RSP = 0xfa,
|
||||
|
|
|
@ -132,7 +132,7 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc)
|
||||
static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t marker, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc)
|
||||
{
|
||||
struct rtp_hdr *rtph;
|
||||
char data[sizeof(*rtph) + payload_len];
|
||||
|
@ -141,7 +141,7 @@ static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t pt, ui
|
|||
rtph = (struct rtp_hdr *)data;
|
||||
len = sizeof(*rtph);
|
||||
rtph->byte0 = RTP_VERSION << 6;
|
||||
rtph->byte1 = pt;
|
||||
rtph->byte1 = pt | (marker << 7);
|
||||
rtph->sequence = htons(sequence);
|
||||
rtph->timestamp = htonl(timestamp);
|
||||
rtph->ssrc = htonl(ssrc);
|
||||
|
@ -321,7 +321,7 @@ connect_error:
|
|||
}
|
||||
|
||||
/* send rtp data with given codec */
|
||||
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, int inc_sequence, int inc_timestamp)
|
||||
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp)
|
||||
{
|
||||
uint8_t *payload = NULL;
|
||||
int payload_len = 0;
|
||||
|
@ -336,7 +336,7 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, in
|
|||
payload_len = len;
|
||||
}
|
||||
|
||||
rtp_send(codec->media->rtp_socket, payload, payload_len, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc);
|
||||
rtp_send(codec->media->rtp_socket, payload, payload_len, marker, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc);
|
||||
codec->media->tx_sequence += inc_sequence;
|
||||
codec->media->tx_timestamp += inc_timestamp;
|
||||
|
||||
|
@ -382,7 +382,7 @@ int osmo_cc_rtp_receive(osmo_cc_session_media_t *media)
|
|||
}
|
||||
|
||||
if (codec->media->receive)
|
||||
codec->media->receiver(codec, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len);
|
||||
codec->media->receiver(codec, marker, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len);
|
||||
|
||||
if (codec->decoder)
|
||||
free(data);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
void osmo_cc_set_rtp_ports(osmo_cc_session_config_t *conf, uint16_t from, uint16_t to);
|
||||
int osmo_cc_rtp_open(osmo_cc_session_media_t *media);
|
||||
int osmo_cc_rtp_connect(osmo_cc_session_media_t *media);
|
||||
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, int inc_sequence, int inc_timestamp);
|
||||
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp);
|
||||
int osmo_cc_rtp_receive(osmo_cc_session_media_t *media);
|
||||
void osmo_cc_rtp_close(osmo_cc_session_media_t *media);
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ void osmo_cc_free_session(osmo_cc_session_t *session)
|
|||
free(session);
|
||||
}
|
||||
|
||||
osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug)
|
||||
osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug)
|
||||
{
|
||||
osmo_cc_session_config_t *conf = session->config;
|
||||
osmo_cc_session_media_t *media, **mediap;
|
||||
|
@ -374,7 +374,7 @@ osmo_cc_session_t *osmo_cc_session_receive_offer(osmo_cc_session_config_t *conf,
|
|||
return session;
|
||||
}
|
||||
|
||||
void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len))
|
||||
void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len))
|
||||
{
|
||||
osmo_cc_session_config_t *conf = media->session->config;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ typedef struct osmo_cc_session_media {
|
|||
osmo_cc_session_connection_data_t connection_data_local, connection_data_remote;
|
||||
struct osmo_cc_session_codec *codec_list;
|
||||
int send, receive;
|
||||
void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
|
||||
void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
|
||||
int rtp_socket;
|
||||
int rtcp_socket;
|
||||
uint32_t tx_ssrc, rx_ssrc;
|
||||
|
@ -110,14 +110,14 @@ typedef struct osmo_cc_session_codec {
|
|||
void osmo_cc_set_local_peer(osmo_cc_session_config_t *conf, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address);
|
||||
osmo_cc_session_t *osmo_cc_new_session(osmo_cc_session_config_t *conf, void *priv, const char *username, const char *sess_id, const char *sess_version, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *unicast_address, const char *session_name, int debug);
|
||||
void osmo_cc_free_session(osmo_cc_session_t *session);
|
||||
osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug);
|
||||
osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug);
|
||||
void osmo_cc_free_media(osmo_cc_session_media_t *media);
|
||||
osmo_cc_session_codec_t *osmo_cc_add_codec(osmo_cc_session_media_t *media, const char *playload_name, uint32_t playload_rate, int playload_channels, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), int debug);
|
||||
void osmo_cc_free_codec(osmo_cc_session_codec_t *codec);
|
||||
int osmo_cc_session_check(struct osmo_cc_session *session, int remote);
|
||||
const char *osmo_cc_session_send_offer(osmo_cc_session_t *session);
|
||||
osmo_cc_session_t *osmo_cc_session_receive_offer(osmo_cc_session_config_t *conf, void *priv, const char *sdp);
|
||||
void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len));
|
||||
void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len));
|
||||
void osmo_cc_session_accept_codec(osmo_cc_session_codec_t *codec, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len));
|
||||
const char *osmo_cc_session_send_answer(osmo_cc_session_t *session);
|
||||
int osmo_cc_session_receive_answer(osmo_cc_session_t *session, const char *sdp);
|
||||
|
|
|
@ -80,7 +80,7 @@ int ph_socket_init(ph_socket_t *s, void (*ph_socket_rx_msg)(ph_socket_t *s, int
|
|||
static void close_connection(ph_socket_t *s)
|
||||
{
|
||||
struct socket_msg_list *ml;
|
||||
uint8_t disable = PH_CTRL_DISABLE;
|
||||
uint8_t disable = PH_CTRL_BLOCK;
|
||||
|
||||
if (s->connect <= 0)
|
||||
return;
|
||||
|
@ -123,7 +123,7 @@ void ph_socket_exit(ph_socket_t *s)
|
|||
|
||||
int ph_socket_work(ph_socket_t *s)
|
||||
{
|
||||
uint8_t enable = PH_CTRL_ENABLE;
|
||||
uint8_t enable = PH_CTRL_UNBLOCK;
|
||||
int rc, flags;
|
||||
int work = 0;
|
||||
|
||||
|
|
|
@ -62,8 +62,8 @@
|
|||
#define PH_MODE_HDLC 0x01 /* HDLC transcoding is performed via B-channel */
|
||||
|
||||
/* one byte sent with control messages */
|
||||
#define PH_CTRL_DISABLE 0x00 /* disable (block) interface, when socket is disconnected */
|
||||
#define PH_CTRL_ENABLE 0x01 /* enable (unblock) interface, when socket is connected */
|
||||
#define PH_CTRL_BLOCK 0x00 /* disable (block) interface, when socket is disconnected */
|
||||
#define PH_CTRL_UNBLOCK 0x01 /* enable (unblock) interface, when socket is connected */
|
||||
#define PH_CTRL_LOOP_DISABLE 0x04 /* disable loopback */
|
||||
#define PH_CTRL_LOOP1_ENABLE 0x05 /* enable LT transceier loopback */
|
||||
#define PH_CTRL_LOOP2_ENABLE 0x06 /* enable NT transceier loopback */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
* of 16 bits signed value:
|
||||
*/
|
||||
static double int_16_speech_level = SPEECH_LEVEL * 0.7079; /* 16 dBm below dBm0, which is about 3dBm below full 16 bit range */
|
||||
static double int_16_1mw_level = 0.7079; /* dBm0, 3dBm below full 16 bit range */
|
||||
|
||||
/* A sample_t is a value that has virtually infinite precision but will also
|
||||
* support high numbers. 'double' or 'float' types are sufficient.
|
||||
|
@ -40,7 +41,8 @@ static double int_16_speech_level = SPEECH_LEVEL * 0.7079; /* 16 dBm below dBm0,
|
|||
* envelope is network dependent.
|
||||
*/
|
||||
|
||||
void samples_to_int16(int16_t *spl, sample_t *samples, int length)
|
||||
/* sample conversion relative to SPEECH level */
|
||||
void samples_to_int16_speech(int16_t *spl, sample_t *samples, int length)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
|
@ -55,10 +57,33 @@ void samples_to_int16(int16_t *spl, sample_t *samples, int length)
|
|||
}
|
||||
}
|
||||
|
||||
void int16_to_samples(sample_t *samples, int16_t *spl, int length)
|
||||
void int16_to_samples_speech(sample_t *samples, int16_t *spl, int length)
|
||||
{
|
||||
while (length--) {
|
||||
*samples++ = (double)(*spl++) / 32767.0 / int_16_speech_level;
|
||||
}
|
||||
}
|
||||
|
||||
/* sample conversion relative to 1mW level */
|
||||
void samples_to_int16_1mw(int16_t *spl, sample_t *samples, int length)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
while (length--) {
|
||||
value = *samples++ * int_16_1mw_level * 32768.0;
|
||||
if (value > 32767.0)
|
||||
*spl++ = 32767;
|
||||
else if (value < -32767.0)
|
||||
*spl++ = -32767;
|
||||
else
|
||||
*spl++ = (uint16_t)value;
|
||||
}
|
||||
}
|
||||
|
||||
void int16_to_samples_1mw(sample_t *samples, int16_t *spl, int length)
|
||||
{
|
||||
while (length--) {
|
||||
*samples++ = (double)(*spl++) / 32767.0 / int_16_1mw_level;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ typedef double sample_t;
|
|||
|
||||
#define SPEECH_LEVEL 0.1585
|
||||
|
||||
void samples_to_int16(int16_t *spl, sample_t *samples, int length);
|
||||
void int16_to_samples(sample_t *samples, int16_t *spl, int length);
|
||||
void samples_to_int16_speech(int16_t *spl, sample_t *samples, int length);
|
||||
void int16_to_samples_speech(sample_t *samples, int16_t *spl, int length);
|
||||
void samples_to_int16_1mw(int16_t *spl, sample_t *samples, int length);
|
||||
void int16_to_samples_1mw(sample_t *samples, int16_t *spl, int length);
|
||||
|
||||
|
|
Loading…
Reference in New Issue