|
|
|
@ -123,6 +123,9 @@ struct codec_ssrc_handler {
|
|
|
|
// silence detection
|
|
|
|
// silence detection
|
|
|
|
GQueue silence_events;
|
|
|
|
GQueue silence_events;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// DTMF send delay
|
|
|
|
|
|
|
|
unsigned long dtmf_first_duration;
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t skip_pts;
|
|
|
|
uint64_t skip_pts;
|
|
|
|
|
|
|
|
|
|
|
|
int rtp_mark:1;
|
|
|
|
int rtp_mark:1;
|
|
|
|
@ -1841,7 +1844,8 @@ static void __output_rtp(struct media_packet *mp, struct codec_ssrc_handler *ch,
|
|
|
|
char *buf, // malloc'd, room for rtp_header + filled-in payload
|
|
|
|
char *buf, // malloc'd, room for rtp_header + filled-in payload
|
|
|
|
unsigned int payload_len,
|
|
|
|
unsigned int payload_len,
|
|
|
|
unsigned long payload_ts,
|
|
|
|
unsigned long payload_ts,
|
|
|
|
int marker, int seq, int seq_inc, int payload_type)
|
|
|
|
int marker, int seq, int seq_inc, int payload_type,
|
|
|
|
|
|
|
|
unsigned long ts_delay)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct rtp_header *rh = (void *) buf;
|
|
|
|
struct rtp_header *rh = (void *) buf;
|
|
|
|
struct ssrc_ctx *ssrc_out = mp->ssrc_out;
|
|
|
|
struct ssrc_ctx *ssrc_out = mp->ssrc_out;
|
|
|
|
@ -1877,6 +1881,7 @@ static void __output_rtp(struct media_packet *mp, struct codec_ssrc_handler *ch,
|
|
|
|
// scale first_send from first_send_ts to ts
|
|
|
|
// scale first_send from first_send_ts to ts
|
|
|
|
p->ttq_entry.when = ch->first_send;
|
|
|
|
p->ttq_entry.when = ch->first_send;
|
|
|
|
uint32_t ts_diff = (uint32_t) ts - (uint32_t) ch->first_send_ts; // allow for wrap-around
|
|
|
|
uint32_t ts_diff = (uint32_t) ts - (uint32_t) ch->first_send_ts; // allow for wrap-around
|
|
|
|
|
|
|
|
ts_diff += ts_delay;
|
|
|
|
long long ts_diff_us =
|
|
|
|
long long ts_diff_us =
|
|
|
|
(unsigned long long) ts_diff * 1000000 / ch->encoder_format.clockrate
|
|
|
|
(unsigned long long) ts_diff * 1000000 / ch->encoder_format.clockrate
|
|
|
|
* ch->handler->dest_pt.codec_def->clockrate_mult;
|
|
|
|
* ch->handler->dest_pt.codec_def->clockrate_mult;
|
|
|
|
@ -1941,6 +1946,7 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe
|
|
|
|
struct media_packet *mp)
|
|
|
|
struct media_packet *mp)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int payload_type = -1; // take from handler's output config
|
|
|
|
int payload_type = -1; // take from handler's output config
|
|
|
|
|
|
|
|
unsigned long ts_delay = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (ch->handler->dtmf_scaler) {
|
|
|
|
if (ch->handler->dtmf_scaler) {
|
|
|
|
struct codec_ssrc_handler *output_ch = NULL;
|
|
|
|
struct codec_ssrc_handler *output_ch = NULL;
|
|
|
|
@ -1956,10 +1962,11 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe
|
|
|
|
goto skip;
|
|
|
|
goto skip;
|
|
|
|
|
|
|
|
|
|
|
|
// init some vars
|
|
|
|
// init some vars
|
|
|
|
if (!ch->first_ts)
|
|
|
|
|
|
|
|
ch->first_ts = output_ch->first_ts;
|
|
|
|
ch->first_ts = output_ch->first_ts;
|
|
|
|
if (!ch->first_send_ts)
|
|
|
|
|
|
|
|
ch->first_send_ts = output_ch->first_send_ts;
|
|
|
|
ch->first_send_ts = output_ch->first_send_ts;
|
|
|
|
|
|
|
|
ch->output_skew = output_ch->output_skew;
|
|
|
|
|
|
|
|
ch->first_send = output_ch->first_send;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// the correct output TS is the encoder's FIFO PTS at the start of the DTMF
|
|
|
|
// the correct output TS is the encoder's FIFO PTS at the start of the DTMF
|
|
|
|
// event. however, we must shift the FIFO PTS forward as the DTMF event goes on
|
|
|
|
// event. however, we must shift the FIFO PTS forward as the DTMF event goes on
|
|
|
|
@ -1989,6 +1996,12 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe
|
|
|
|
ch->handler->dest_pt.clock_rate, ch->handler->source_pt.clock_rate);
|
|
|
|
ch->handler->dest_pt.clock_rate, ch->handler->source_pt.clock_rate);
|
|
|
|
dtmf->duration = htons(duration);
|
|
|
|
dtmf->duration = htons(duration);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// we can't directly use the RTP TS to schedule the send, as we have to adjust it
|
|
|
|
|
|
|
|
// by the duration
|
|
|
|
|
|
|
|
if (ch->dtmf_first_duration == 0 || duration < ch->dtmf_first_duration)
|
|
|
|
|
|
|
|
ch->dtmf_first_duration = duration;
|
|
|
|
|
|
|
|
ts_delay = duration - ch->dtmf_first_duration;
|
|
|
|
|
|
|
|
|
|
|
|
// shift forward our output RTP TS
|
|
|
|
// shift forward our output RTP TS
|
|
|
|
output_ch->encoder->next_pts = (ts + duration) * output_ch->encoder->def->clockrate_mult;
|
|
|
|
output_ch->encoder->next_pts = (ts + duration) * output_ch->encoder->def->clockrate_mult;
|
|
|
|
output_ch->encoder->packet_pts += (duration - ch->last_dtmf_event_ts) * output_ch->encoder->def->clockrate_mult;
|
|
|
|
output_ch->encoder->packet_pts += (duration - ch->last_dtmf_event_ts) * output_ch->encoder->def->clockrate_mult;
|
|
|
|
@ -2006,10 +2019,10 @@ skip:
|
|
|
|
memcpy(buf + sizeof(struct rtp_header), packet->payload->s, packet->payload->len);
|
|
|
|
memcpy(buf + sizeof(struct rtp_header), packet->payload->s, packet->payload->len);
|
|
|
|
if (packet->ignore_seq) // inject original seq
|
|
|
|
if (packet->ignore_seq) // inject original seq
|
|
|
|
__output_rtp(mp, ch, packet->handler ? : ch->handler, buf, packet->payload->len, packet->ts,
|
|
|
|
__output_rtp(mp, ch, packet->handler ? : ch->handler, buf, packet->payload->len, packet->ts,
|
|
|
|
packet->marker, packet->p.seq, -1, payload_type);
|
|
|
|
packet->marker, packet->p.seq, -1, payload_type, ts_delay);
|
|
|
|
else // use our own sequencing
|
|
|
|
else // use our own sequencing
|
|
|
|
__output_rtp(mp, ch, packet->handler ? : ch->handler, buf, packet->payload->len, packet->ts,
|
|
|
|
__output_rtp(mp, ch, packet->handler ? : ch->handler, buf, packet->payload->len, packet->ts,
|
|
|
|
packet->marker, -1, 0, payload_type);
|
|
|
|
packet->marker, -1, 0, payload_type, ts_delay);
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -2809,7 +2822,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) {
|
|
|
|
__output_rtp(mp, ch, ch->handler, send_buf, inout.len, ch->first_ts
|
|
|
|
__output_rtp(mp, ch, ch->handler, send_buf, inout.len, ch->first_ts
|
|
|
|
+ enc->avpkt.pts / enc->def->clockrate_mult,
|
|
|
|
+ enc->avpkt.pts / enc->def->clockrate_mult,
|
|
|
|
ch->rtp_mark ? 1 : 0, -1, 0,
|
|
|
|
ch->rtp_mark ? 1 : 0, -1, 0,
|
|
|
|
payload_type);
|
|
|
|
payload_type, 0);
|
|
|
|
mp->ssrc_out->parent->seq_diff++;
|
|
|
|
mp->ssrc_out->parent->seq_diff++;
|
|
|
|
//mp->iter_out++;
|
|
|
|
//mp->iter_out++;
|
|
|
|
ch->rtp_mark = 0;
|
|
|
|
ch->rtp_mark = 0;
|
|
|
|
|