|
|
|
@ -33,6 +33,11 @@ struct mqtt_timer { |
|
|
|
struct call_media *media; |
|
|
|
}; |
|
|
|
|
|
|
|
typedef void (*raw_input_func_t)(struct media_packet *mp, unsigned int); |
|
|
|
|
|
|
|
static void __buffer_delay_raw(struct delay_buffer *dbuf, |
|
|
|
raw_input_func_t input_func, struct media_packet *mp, unsigned int clockrate); |
|
|
|
|
|
|
|
|
|
|
|
static codec_handler_func handler_func_passthrough; |
|
|
|
static struct timerthread codec_timers_thread; |
|
|
|
@ -127,7 +132,9 @@ struct delay_buffer { |
|
|
|
struct delay_frame { |
|
|
|
AVFrame *frame; |
|
|
|
struct media_packet mp; |
|
|
|
encoder_input_func_t func; |
|
|
|
unsigned int clockrate; |
|
|
|
encoder_input_func_t encoder_func; |
|
|
|
raw_input_func_t raw_func; |
|
|
|
struct codec_handler *handler; |
|
|
|
struct codec_ssrc_handler *ch; |
|
|
|
}; |
|
|
|
@ -325,6 +332,14 @@ static void __make_passthrough(struct codec_handler *handler, int dtmf_pt, int c |
|
|
|
handler->dtmf_payload_type = dtmf_pt; |
|
|
|
handler->cn_payload_type = cn_pt; |
|
|
|
handler->passthrough = 1; |
|
|
|
|
|
|
|
#ifdef WITH_TRANSCODING |
|
|
|
if (handler->media->buffer_delay) { |
|
|
|
__delay_buffer_setup(&handler->delay_buffer, handler, handler->media->call, |
|
|
|
handler->media->buffer_delay); |
|
|
|
handler->kernelize = 0; |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
static void __make_passthrough_ssrc(struct codec_handler *handler) { |
|
|
|
int dtmf_pt = handler->dtmf_payload_type; |
|
|
|
@ -344,6 +359,14 @@ static void __make_passthrough_ssrc(struct codec_handler *handler) { |
|
|
|
handler->dtmf_payload_type = dtmf_pt; |
|
|
|
handler->cn_payload_type = cn_pt; |
|
|
|
handler->passthrough = 1; |
|
|
|
|
|
|
|
#ifdef WITH_TRANSCODING |
|
|
|
if (handler->media->buffer_delay) { |
|
|
|
__delay_buffer_setup(&handler->delay_buffer, handler, handler->media->call, |
|
|
|
handler->media->buffer_delay); |
|
|
|
handler->kernelize = 0; |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
static void __reset_sequencer(void *p, void *dummy) { |
|
|
|
@ -1378,7 +1401,9 @@ static int handler_func_passthrough(struct codec_handler *h, struct media_packet |
|
|
|
codec_calc_jitter(mp->ssrc_in, ntohl(mp->rtp->timestamp), h->source_pt.clock_rate, &mp->tv); |
|
|
|
codec_calc_lost(mp->ssrc_in, ntohs(mp->rtp->seq_num)); |
|
|
|
} |
|
|
|
codec_add_raw_packet(mp, h->source_pt.clock_rate); |
|
|
|
|
|
|
|
__buffer_delay_raw(h->delay_buffer, codec_add_raw_packet, mp, h->source_pt.clock_rate); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
@ -2032,7 +2057,8 @@ static int handler_func_passthrough_ssrc(struct codec_handler *h, struct media_p |
|
|
|
|
|
|
|
// keep track of other stats here? |
|
|
|
|
|
|
|
codec_add_raw_packet(mp, h->source_pt.clock_rate); |
|
|
|
__buffer_delay_raw(h->delay_buffer, codec_add_raw_packet, mp, h->source_pt.clock_rate); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
@ -2154,7 +2180,7 @@ static void __buffer_delay_frame(struct delay_buffer *dbuf, struct codec_ssrc_ha |
|
|
|
|
|
|
|
struct delay_frame *dframe = g_slice_alloc0(sizeof(*dframe)); |
|
|
|
dframe->frame = frame; |
|
|
|
dframe->func = input_func; |
|
|
|
dframe->encoder_func = input_func; |
|
|
|
dframe->ch = obj_get(&ch->h); |
|
|
|
media_packet_copy(&dframe->mp, mp); |
|
|
|
|
|
|
|
@ -2165,6 +2191,31 @@ static void __buffer_delay_frame(struct delay_buffer *dbuf, struct codec_ssrc_ha |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
static void __buffer_delay_raw(struct delay_buffer *dbuf, |
|
|
|
raw_input_func_t input_func, struct media_packet *mp, unsigned int clockrate) |
|
|
|
{ |
|
|
|
if (__buffer_delay_do_direct(dbuf)) { |
|
|
|
// direct passthrough |
|
|
|
input_func(mp, clockrate); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
struct delay_frame *dframe = g_slice_alloc0(sizeof(*dframe)); |
|
|
|
dframe->raw_func = input_func; |
|
|
|
dframe->clockrate = clockrate; |
|
|
|
media_packet_copy(&dframe->mp, mp); |
|
|
|
|
|
|
|
// also copy packet payload |
|
|
|
dframe->mp.raw = mp->raw; |
|
|
|
dframe->mp.raw.s = g_malloc(mp->raw.len + RTP_BUFFER_TAIL_ROOM); |
|
|
|
memcpy(dframe->mp.raw.s, mp->raw.s, mp->raw.len); |
|
|
|
|
|
|
|
LOCK(&dbuf->lock); |
|
|
|
g_queue_insert_sorted(&dbuf->frames, dframe, delay_frame_cmp, NULL); |
|
|
|
|
|
|
|
__delay_buffer_schedule(dbuf); |
|
|
|
} |
|
|
|
|
|
|
|
// consumes `packet` if buffered (returns 1) |
|
|
|
static int __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *decoder_handler, |
|
|
|
struct codec_ssrc_handler *input_handler, |
|
|
|
@ -2215,8 +2266,9 @@ static int __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *deco |
|
|
|
} |
|
|
|
|
|
|
|
static void delay_frame_free(struct delay_frame *dframe) { |
|
|
|
media_packet_release(&dframe->mp); |
|
|
|
av_frame_free(&dframe->frame); |
|
|
|
g_free(dframe->mp.raw.s); |
|
|
|
media_packet_release(&dframe->mp); |
|
|
|
if (dframe->ch) |
|
|
|
obj_put(&dframe->ch->h); |
|
|
|
g_slice_free1(sizeof(*dframe), dframe); |
|
|
|
@ -2276,9 +2328,11 @@ static void __delay_frame_process(struct delay_buffer *dbuf, struct delay_frame |
|
|
|
struct codec_ssrc_handler *csh = dframe->ch; |
|
|
|
|
|
|
|
if (csh && csh->handler && csh->encoder) { |
|
|
|
dframe->func(csh->encoder, dframe->frame, csh->handler->packet_encoded, |
|
|
|
dframe->encoder_func(csh->encoder, dframe->frame, csh->handler->packet_encoded, |
|
|
|
csh, &dframe->mp); |
|
|
|
} |
|
|
|
else if (dframe->raw_func) |
|
|
|
dframe->raw_func(&dframe->mp, dframe->clockrate); |
|
|
|
else |
|
|
|
ilog(LOG_ERR | LOG_FLAG_LIMIT, "Delay buffer bug"); |
|
|
|
} |
|
|
|
@ -2729,6 +2783,8 @@ static void __delay_buffer_setup(struct delay_buffer **dbufp, |
|
|
|
dbuf->call = obj_get(call); |
|
|
|
dbuf->delay = delay; |
|
|
|
mutex_init(&dbuf->lock); |
|
|
|
|
|
|
|
*dbufp = dbuf; |
|
|
|
} |
|
|
|
static void __ssrc_handler_stop(void *p, void *dummy) { |
|
|
|
struct codec_ssrc_handler *ch = p; |
|
|
|
@ -3194,6 +3250,15 @@ out: |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
// dummy/stub |
|
|
|
static void __buffer_delay_raw(struct delay_buffer *dbuf, |
|
|
|
raw_input_func_t input_func, struct media_packet *mp, unsigned int clockrate) |
|
|
|
{ |
|
|
|
input_func(mp, clockrate); |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|