|
|
|
|
@ -24,7 +24,7 @@
|
|
|
|
|
struct codec_timer {
|
|
|
|
|
struct timerthread_obj tt_obj;
|
|
|
|
|
struct timeval next;
|
|
|
|
|
void (*func)(struct codec_timer *);
|
|
|
|
|
void (*timer_func)(struct codec_timer *);
|
|
|
|
|
};
|
|
|
|
|
struct mqtt_timer {
|
|
|
|
|
struct codec_timer ct;
|
|
|
|
|
@ -34,7 +34,7 @@ struct mqtt_timer {
|
|
|
|
|
};
|
|
|
|
|
struct timer_callback {
|
|
|
|
|
struct codec_timer ct;
|
|
|
|
|
void (*func)(struct call *, void *);
|
|
|
|
|
void (*timer_callback_func)(struct call *, void *);
|
|
|
|
|
struct call *call;
|
|
|
|
|
void *ptr;
|
|
|
|
|
};
|
|
|
|
|
@ -57,7 +57,7 @@ static void codec_calc_lost(struct ssrc_ctx *ssrc, uint16_t seq);
|
|
|
|
|
static struct codec_handler codec_handler_stub = {
|
|
|
|
|
.source_pt.payload_type = -1,
|
|
|
|
|
.dest_pt.payload_type = -1,
|
|
|
|
|
.func = handler_func_passthrough,
|
|
|
|
|
.handler_func = handler_func_passthrough,
|
|
|
|
|
.kernelize = 1,
|
|
|
|
|
.passthrough = 1,
|
|
|
|
|
};
|
|
|
|
|
@ -120,7 +120,7 @@ struct dtx_packet {
|
|
|
|
|
struct media_packet mp;
|
|
|
|
|
struct codec_ssrc_handler *decoder_handler; // holds reference
|
|
|
|
|
struct codec_ssrc_handler *input_handler; // holds reference
|
|
|
|
|
int (*func)(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
|
|
|
|
|
int (*dtx_func)(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
|
|
|
|
|
struct transcode_packet *packet, struct media_packet *mp);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -207,7 +207,7 @@ struct transcode_packet {
|
|
|
|
|
struct codec_handler *handler;
|
|
|
|
|
unsigned int marker:1,
|
|
|
|
|
bypass_seq:1;
|
|
|
|
|
int (*func)(struct codec_ssrc_handler *, struct codec_ssrc_handler *, struct transcode_packet *,
|
|
|
|
|
int (*packet_func)(struct codec_ssrc_handler *, struct codec_ssrc_handler *, struct transcode_packet *,
|
|
|
|
|
struct media_packet *);
|
|
|
|
|
int (*dup_func)(struct codec_ssrc_handler *, struct codec_ssrc_handler *, struct transcode_packet *,
|
|
|
|
|
struct media_packet *);
|
|
|
|
|
@ -253,7 +253,7 @@ static void codec_touched(struct codec_store *cs, struct rtp_payload_type *pt);
|
|
|
|
|
static int __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *ch,
|
|
|
|
|
struct codec_ssrc_handler *input_handler,
|
|
|
|
|
struct transcode_packet *packet, struct media_packet *mp,
|
|
|
|
|
int (*func)(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
|
|
|
|
|
int (*dtx_func)(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
|
|
|
|
|
struct transcode_packet *packet,
|
|
|
|
|
struct media_packet *mp));
|
|
|
|
|
static void __dtx_shutdown(struct dtx_buffer *dtxb);
|
|
|
|
|
@ -277,7 +277,7 @@ static void __buffer_delay_seq(struct delay_buffer *dbuf, struct media_packet *m
|
|
|
|
|
static struct codec_handler codec_handler_stub_ssrc = {
|
|
|
|
|
.source_pt.payload_type = -1,
|
|
|
|
|
.dest_pt.payload_type = -1,
|
|
|
|
|
.func = handler_func_passthrough_ssrc,
|
|
|
|
|
.handler_func = handler_func_passthrough_ssrc,
|
|
|
|
|
.kernelize = 1,
|
|
|
|
|
.passthrough = 1,
|
|
|
|
|
};
|
|
|
|
|
@ -349,9 +349,9 @@ static void __make_passthrough(struct codec_handler *handler, int dtmf_pt, int c
|
|
|
|
|
ilogs(codec, LOG_DEBUG, "Using passthrough handler for " STR_FORMAT " with DTMF %i, CN %i",
|
|
|
|
|
STR_FMT(&handler->source_pt.encoding_with_params), dtmf_pt, cn_pt);
|
|
|
|
|
if (handler->source_pt.codec_def && handler->source_pt.codec_def->dtmf)
|
|
|
|
|
handler->func = handler_func_dtmf;
|
|
|
|
|
handler->handler_func = handler_func_dtmf;
|
|
|
|
|
else {
|
|
|
|
|
handler->func = handler_func_passthrough;
|
|
|
|
|
handler->handler_func = handler_func_passthrough;
|
|
|
|
|
handler->kernelize = 1;
|
|
|
|
|
}
|
|
|
|
|
rtp_payload_type_copy(&handler->dest_pt, &handler->source_pt);
|
|
|
|
|
@ -376,9 +376,9 @@ static void __make_passthrough_ssrc(struct codec_handler *handler) {
|
|
|
|
|
ilogs(codec, LOG_DEBUG, "Using passthrough handler with new SSRC for " STR_FORMAT,
|
|
|
|
|
STR_FMT(&handler->source_pt.encoding_with_params));
|
|
|
|
|
if (handler->source_pt.codec_def && handler->source_pt.codec_def->dtmf)
|
|
|
|
|
handler->func = handler_func_dtmf;
|
|
|
|
|
handler->handler_func = handler_func_dtmf;
|
|
|
|
|
else {
|
|
|
|
|
handler->func = handler_func_passthrough_ssrc;
|
|
|
|
|
handler->handler_func = handler_func_passthrough_ssrc;
|
|
|
|
|
handler->kernelize = 1;
|
|
|
|
|
}
|
|
|
|
|
rtp_payload_type_copy(&handler->dest_pt, &handler->source_pt);
|
|
|
|
|
@ -413,7 +413,7 @@ static void __make_transcoder(struct codec_handler *handler, struct rtp_payload_
|
|
|
|
|
goto reset;
|
|
|
|
|
if (rtp_payload_type_cmp(dest, &handler->dest_pt))
|
|
|
|
|
goto reset;
|
|
|
|
|
if (handler->func != handler_func_transcode)
|
|
|
|
|
if (handler->handler_func != handler_func_transcode)
|
|
|
|
|
goto reset;
|
|
|
|
|
if (handler->cn_payload_type != cn_payload_type)
|
|
|
|
|
goto reset;
|
|
|
|
|
@ -434,7 +434,7 @@ reset:
|
|
|
|
|
__handler_shutdown(handler);
|
|
|
|
|
|
|
|
|
|
rtp_payload_type_copy(&handler->dest_pt, dest);
|
|
|
|
|
handler->func = handler_func_transcode;
|
|
|
|
|
handler->handler_func = handler_func_transcode;
|
|
|
|
|
handler->transcoder = 1;
|
|
|
|
|
handler->dtmf_payload_type = dtmf_payload_type;
|
|
|
|
|
handler->cn_payload_type = cn_payload_type;
|
|
|
|
|
@ -442,7 +442,7 @@ reset:
|
|
|
|
|
|
|
|
|
|
// DTMF transcoder/scaler?
|
|
|
|
|
if (handler->source_pt.codec_def && handler->source_pt.codec_def->dtmf)
|
|
|
|
|
handler->func = handler_func_dtmf;
|
|
|
|
|
handler->handler_func = handler_func_dtmf;
|
|
|
|
|
|
|
|
|
|
ilogs(codec, LOG_DEBUG, "Created transcode context for " STR_FORMAT " (%i) -> " STR_FORMAT
|
|
|
|
|
" (%i) with DTMF output %i and CN output %i",
|
|
|
|
|
@ -500,7 +500,7 @@ struct codec_handler *codec_handler_make_playback(const struct rtp_payload_type
|
|
|
|
|
{
|
|
|
|
|
struct codec_handler *handler = __handler_new(src_pt, media, NULL);
|
|
|
|
|
rtp_payload_type_copy(&handler->dest_pt, dst_pt);
|
|
|
|
|
handler->func = handler_func_playback;
|
|
|
|
|
handler->handler_func = handler_func_playback;
|
|
|
|
|
handler->ssrc_handler = (void *) __ssrc_handler_transcode_new(handler);
|
|
|
|
|
handler->ssrc_handler->first_ts = last_ts;
|
|
|
|
|
while (handler->ssrc_handler->first_ts == 0)
|
|
|
|
|
@ -684,7 +684,7 @@ static void __check_dtmf_injector(struct call_media *receiver, struct call_media
|
|
|
|
|
|
|
|
|
|
parent->dtmf_injector = __handler_new(&src_pt, receiver, sink);
|
|
|
|
|
__make_transcoder(parent->dtmf_injector, &parent->dest_pt, output_transcoders, -1, 0, -1);
|
|
|
|
|
parent->dtmf_injector->func = handler_func_inject_dtmf;
|
|
|
|
|
parent->dtmf_injector->handler_func = handler_func_inject_dtmf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -732,7 +732,7 @@ static void __check_t38_decoder(struct call_media *t38_media) {
|
|
|
|
|
return;
|
|
|
|
|
ilogs(codec, LOG_DEBUG, "Creating T.38 packet handler");
|
|
|
|
|
t38_media->t38_handler = __handler_new(NULL, t38_media, NULL);
|
|
|
|
|
t38_media->t38_handler->func = handler_func_t38;
|
|
|
|
|
t38_media->t38_handler->handler_func = handler_func_t38;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int packet_encoded_t38(encoder_t *enc, void *u1, void *u2) {
|
|
|
|
|
@ -863,7 +863,7 @@ static void __codec_rtcp_timer_schedule(struct call_media *media) {
|
|
|
|
|
rt->call = obj_get(media->call);
|
|
|
|
|
rt->media = media;
|
|
|
|
|
rt->ct.next = rtpe_now;
|
|
|
|
|
rt->ct.func = __rtcp_timer_run;
|
|
|
|
|
rt->ct.timer_func = __rtcp_timer_run;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timeval_add_usec(&rt->ct.next, 5000000 + (ssl_random() % 2000000));
|
|
|
|
|
@ -1398,7 +1398,7 @@ void mqtt_timer_start(struct mqtt_timer **mqtp, struct call *call, struct call_m
|
|
|
|
|
mqt->self = mqtp;
|
|
|
|
|
mqt->media = media;
|
|
|
|
|
mqt->ct.next = rtpe_now;
|
|
|
|
|
mqt->ct.func = __mqtt_timer_run;
|
|
|
|
|
mqt->ct.timer_func = __mqtt_timer_run;
|
|
|
|
|
|
|
|
|
|
__codec_mqtt_timer_schedule(mqt);
|
|
|
|
|
}
|
|
|
|
|
@ -1540,8 +1540,8 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa
|
|
|
|
|
struct codec_handler *h = packet->handler;
|
|
|
|
|
|
|
|
|
|
if (G_UNLIKELY(!h->ssrc_hash)) {
|
|
|
|
|
if (!packet->func || !h->input_handler->ssrc_hash) {
|
|
|
|
|
h->func(h, mp);
|
|
|
|
|
if (!packet->packet_func || !h->input_handler->ssrc_hash) {
|
|
|
|
|
h->handler_func(h, mp);
|
|
|
|
|
__transcode_packet_free(packet);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@ -1573,7 +1573,7 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa
|
|
|
|
|
if (packet->bypass_seq) {
|
|
|
|
|
// bypass sequencer
|
|
|
|
|
__ssrc_lock_both(mp);
|
|
|
|
|
int ret = packet->func(ch, ch, packet, mp);
|
|
|
|
|
int ret = packet->packet_func(ch, ch, packet, mp);
|
|
|
|
|
if (ret != 1)
|
|
|
|
|
__transcode_packet_free(packet);
|
|
|
|
|
__ssrc_unlock_both(mp);
|
|
|
|
|
@ -1687,7 +1687,7 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa
|
|
|
|
|
// we might be working with a different packet now
|
|
|
|
|
mp->rtp = &packet->rtp;
|
|
|
|
|
|
|
|
|
|
func_ret = packet->func(ch, input_ch, packet, mp);
|
|
|
|
|
func_ret = packet->packet_func(ch, input_ch, packet, mp);
|
|
|
|
|
if (func_ret < 0)
|
|
|
|
|
ilogs(transcoding, LOG_WARN | LOG_FLAG_LIMIT, "Decoder error while processing RTP packet");
|
|
|
|
|
next:
|
|
|
|
|
@ -2000,7 +2000,7 @@ static int packet_dtmf_dup(struct codec_ssrc_handler *ch, struct codec_ssrc_hand
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int __handler_func_supplemental(struct codec_handler *h, struct media_packet *mp,
|
|
|
|
|
int (*func)(struct codec_ssrc_handler *, struct codec_ssrc_handler *,
|
|
|
|
|
int (*packet_func)(struct codec_ssrc_handler *, struct codec_ssrc_handler *,
|
|
|
|
|
struct transcode_packet *, struct media_packet *),
|
|
|
|
|
int (*dup_func)(struct codec_ssrc_handler *, struct codec_ssrc_handler *,
|
|
|
|
|
struct transcode_packet *, struct media_packet *))
|
|
|
|
|
@ -2027,7 +2027,7 @@ static int __handler_func_supplemental(struct codec_handler *h, struct media_pac
|
|
|
|
|
h->output_handler = sequencer_h;
|
|
|
|
|
|
|
|
|
|
struct transcode_packet *packet = g_slice_alloc0(sizeof(*packet));
|
|
|
|
|
packet->func = func;
|
|
|
|
|
packet->packet_func = packet_func;
|
|
|
|
|
packet->dup_func = dup_func;
|
|
|
|
|
packet->handler = h;
|
|
|
|
|
packet->rtp = *mp->rtp;
|
|
|
|
|
@ -2429,7 +2429,7 @@ static void __buffer_delay_seq(struct delay_buffer *dbuf, struct media_packet *m
|
|
|
|
|
static int __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *decoder_handler,
|
|
|
|
|
struct codec_ssrc_handler *input_handler,
|
|
|
|
|
struct transcode_packet *packet, struct media_packet *mp,
|
|
|
|
|
int (*func)(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
|
|
|
|
|
int (*dtx_func)(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
|
|
|
|
|
struct transcode_packet *packet,
|
|
|
|
|
struct media_packet *mp))
|
|
|
|
|
{
|
|
|
|
|
@ -2441,7 +2441,7 @@ static int __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *deco
|
|
|
|
|
// allocate packet object
|
|
|
|
|
struct dtx_packet *dtxp = g_slice_alloc0(sizeof(*dtxp));
|
|
|
|
|
dtxp->packet = packet;
|
|
|
|
|
dtxp->func = func;
|
|
|
|
|
dtxp->dtx_func = dtx_func;
|
|
|
|
|
if (decoder_handler)
|
|
|
|
|
dtxp->decoder_handler = obj_get(&decoder_handler->h);
|
|
|
|
|
if (input_handler)
|
|
|
|
|
@ -2982,7 +2982,7 @@ static void __dtx_send_later(struct codec_timer *ct) {
|
|
|
|
|
"%i packets left in queue", ts, p_left);
|
|
|
|
|
|
|
|
|
|
mp_copy.ptime = -1;
|
|
|
|
|
ret = dtxp->func(ch, input_ch, dtxp->packet, &mp_copy);
|
|
|
|
|
ret = dtxp->dtx_func(ch, input_ch, dtxp->packet, &mp_copy);
|
|
|
|
|
if (!ret) {
|
|
|
|
|
if (mp_copy.ptime > 0)
|
|
|
|
|
ptime = mp_copy.ptime;
|
|
|
|
|
@ -3106,7 +3106,7 @@ static void __dtx_setup(struct codec_ssrc_handler *ch) {
|
|
|
|
|
struct dtx_buffer *dtx =
|
|
|
|
|
ch->dtx_buffer = obj_alloc0("dtx_buffer", sizeof(*dtx), __dtx_free);
|
|
|
|
|
dtx->ct.tt_obj.tt = &codec_timers_thread;
|
|
|
|
|
dtx->ct.func = __dtx_send_later;
|
|
|
|
|
dtx->ct.timer_func = __dtx_send_later;
|
|
|
|
|
dtx->csh = obj_get(&ch->h);
|
|
|
|
|
dtx->call = obj_get(ch->handler->media->call);
|
|
|
|
|
mutex_init(&dtx->lock);
|
|
|
|
|
@ -3138,7 +3138,7 @@ static void __delay_buffer_setup(struct delay_buffer **dbufp,
|
|
|
|
|
|
|
|
|
|
dbuf = obj_alloc0("delay_buffer", sizeof(*dbuf), __delay_buffer_free);
|
|
|
|
|
dbuf->ct.tt_obj.tt = &codec_timers_thread;
|
|
|
|
|
dbuf->ct.func = __delay_send_later;
|
|
|
|
|
dbuf->ct.timer_func = __delay_send_later;
|
|
|
|
|
dbuf->handler = h;
|
|
|
|
|
dbuf->call = obj_get(call);
|
|
|
|
|
dbuf->delay = delay;
|
|
|
|
|
@ -3778,7 +3778,7 @@ static int handler_func_transcode(struct codec_handler *h, struct media_packet *
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct transcode_packet *packet = g_slice_alloc0(sizeof(*packet));
|
|
|
|
|
packet->func = packet_decode;
|
|
|
|
|
packet->packet_func = packet_decode;
|
|
|
|
|
packet->rtp = *mp->rtp;
|
|
|
|
|
packet->handler = h;
|
|
|
|
|
|
|
|
|
|
@ -4797,7 +4797,7 @@ static void __codec_timer_callback_free(void *p) {
|
|
|
|
|
static void __codec_timer_callback_fire(struct codec_timer *ct) {
|
|
|
|
|
struct timer_callback *cb = (void *) ct;
|
|
|
|
|
log_info_call(cb->call);
|
|
|
|
|
cb->func(cb->call, cb->ptr);
|
|
|
|
|
cb->timer_callback_func(cb->call, cb->ptr);
|
|
|
|
|
codec_timer_stop(&ct);
|
|
|
|
|
log_info_pop();
|
|
|
|
|
}
|
|
|
|
|
@ -4805,9 +4805,9 @@ void codec_timer_callback(struct call *c, void (*func)(struct call *, void *), v
|
|
|
|
|
struct timer_callback *cb = obj_alloc0("codec_timer_callback", sizeof(*cb), __codec_timer_callback_free);
|
|
|
|
|
cb->ct.tt_obj.tt = &codec_timers_thread;
|
|
|
|
|
cb->call = obj_get(c);
|
|
|
|
|
cb->func = func;
|
|
|
|
|
cb->timer_callback_func = func;
|
|
|
|
|
cb->ptr = p;
|
|
|
|
|
cb->ct.func = __codec_timer_callback_fire;
|
|
|
|
|
cb->ct.timer_func = __codec_timer_callback_fire;
|
|
|
|
|
cb->ct.next = rtpe_now;
|
|
|
|
|
timeval_add_usec(&cb->ct.next, delay);
|
|
|
|
|
timerthread_obj_schedule_abs(&cb->ct.tt_obj, &cb->ct.next);
|
|
|
|
|
@ -4815,7 +4815,7 @@ void codec_timer_callback(struct call *c, void (*func)(struct call *, void *), v
|
|
|
|
|
|
|
|
|
|
static void codec_timers_run(void *p) {
|
|
|
|
|
struct codec_timer *ct = p;
|
|
|
|
|
ct->func(ct);
|
|
|
|
|
ct->timer_func(ct);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void codecs_init(void) {
|
|
|
|
|
|