TT#136957 peg seq num tracking to position in delay buffer

Change-Id: Ic78f24d2593817832839d3e1cf7ce3b398be785e
pull/1430/head
Richard Fuchs 4 years ago
parent 2ca64340e1
commit 3a90f44383

@ -154,6 +154,7 @@ struct delay_frame {
struct codec_handler *handler;
struct codec_ssrc_handler *ch;
struct codec_ssrc_handler *input_ch;
int seq_adj;
};
struct silence_event {
@ -270,6 +271,7 @@ static int __buffer_delay_packet(struct delay_buffer *dbuf,
unsigned long ts_delay,
int payload_type,
packet_input_func_t packet_func, struct media_packet *mp, unsigned int clockrate);
static void __buffer_delay_seq(struct delay_buffer *dbuf, struct media_packet *mp, int seq_adj);
static struct codec_handler codec_handler_stub_ssrc = {
@ -1889,7 +1891,7 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct codec_ssrc_hand
int ret = __buffer_delay_packet(input_h->delay_buffer, ch, input_ch, packet, ts_delay, payload_type,
codec_add_dtmf_packet, mp, h->source_pt.clock_rate);
mp->ssrc_out->parent->seq_diff--;
__buffer_delay_seq(input_h->delay_buffer, mp, -1);
return ret;
}
@ -2287,13 +2289,16 @@ static int delay_frame_cmp(const void *A, const void *B, void *ptr) {
}
// consumes frame
// `frame` can be NULL (discarded/lost packet)
static void __buffer_delay_frame(struct delay_buffer *dbuf, struct codec_ssrc_handler *ch,
encoder_input_func_t input_func, AVFrame *frame, struct media_packet *mp, uint32_t ts)
{
if (__buffer_delay_do_direct(dbuf)) {
// input now
input_func(ch->encoder, frame, ch->handler->packet_encoded, ch, mp);
av_frame_free(&frame);
if (frame) {
input_func(ch->encoder, frame, ch->handler->packet_encoded, ch, mp);
av_frame_free(&frame);
}
return;
}
@ -2373,7 +2378,29 @@ static int __buffer_delay_packet(struct delay_buffer *dbuf,
return 1;
}
static void __buffer_delay_seq(struct delay_buffer *dbuf, struct media_packet *mp, int seq_adj) {
if (!mp->ssrc_out)
return;
if (__buffer_delay_do_direct(dbuf)) {
mp->ssrc_out->parent->seq_diff += seq_adj;
return;
}
LOCK(&dbuf->lock);
// peg the adjustment to the most recent frame if any
struct delay_frame *dframe = g_queue_peek_head(&dbuf->frames);
if (!dframe) {
mp->ssrc_out->parent->seq_diff += seq_adj;
return;
}
dframe->seq_adj += seq_adj;
}
// consumes `packet` if buffered (returns 1)
// `packet` can be NULL (discarded packet for seq tracking)
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,
@ -2384,7 +2411,7 @@ static int __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *deco
if (!dtxb || !mp->sfd || !mp->ssrc_in || !mp->ssrc_out)
return 0;
unsigned long ts = packet->ts;
unsigned long ts = packet ? packet->ts : 0;
// allocate packet object
struct dtx_packet *dtxp = g_slice_alloc0(sizeof(*dtxp));
@ -2414,12 +2441,13 @@ static int __buffer_dtx(struct dtx_buffer *dtxb, struct codec_ssrc_handler *deco
timerthread_obj_schedule_abs(&dtxb->ct.tt_obj, &dtxb->ct.next);
}
// packet now consumed
// packet now consumed if there was one
int ret = packet ? 0 : 1;
packet = NULL;
mutex_unlock(&dtxb->lock);
return 1;
return ret;
}
static void delay_frame_free(struct delay_frame *dframe) {
@ -2558,15 +2586,6 @@ static void delay_packet_manipulate(struct delay_frame *dframe) {
}
}
static void __delay_frame_process(struct delay_buffer *dbuf, struct delay_frame *dframe) {
if (dframe->mp.rtp) {
// adjust output seq num. pushing packets into the delay buffer looks as if they
// were consumed and resulted in a decreased seq_diff. we need to adjust the
// perceived seq num forward to compensate for this. each entry in the buffer
// accounts for one packet that was only delayed and not consumed:
//LOCK(&dbuf->lock); // XXX needed?
dframe->mp.rtp->seq_num = htons(ntohs(dframe->mp.rtp->seq_num) + dbuf->frames.length + 1);
}
struct codec_ssrc_handler *csh = dframe->ch;
if (csh && csh->handler && csh->encoder && dframe->encoder_func) {
@ -2583,8 +2602,9 @@ static void __delay_frame_process(struct delay_buffer *dbuf, struct delay_frame
dframe->packet_func(csh, dframe->input_ch, dframe->packet, dframe->ts_delay,
dframe->payload_type, &dframe->mp);
}
else
ilog(LOG_ERR | LOG_FLAG_LIMIT, "Delay buffer bug");
if (dframe->seq_adj)
dframe->mp.ssrc_out->parent->seq_diff += dframe->seq_adj;
}
static void __delay_send_later(struct codec_timer *ct) {
struct delay_buffer *dbuf = (void *) ct;
@ -3441,7 +3461,8 @@ static int packet_decoded_common(decoder_t *decoder, AVFrame *frame, void *u1, v
ch->encoder->codec_options.amr.cmr = mp->media_out->u.amr.cmr;
uint32_t ts = mp->rtp ? ntohl(mp->rtp->timestamp) : frame->pts;
__buffer_delay_frame(h->delay_buffer, ch, input_func, frame, mp, ts);
__buffer_delay_frame(h->input_handler ? h->input_handler->delay_buffer : h->delay_buffer,
ch, input_func, frame, mp, ts);
frame = NULL; // consumed
discard:
@ -3461,10 +3482,12 @@ static int packet_decoded_direct(decoder_t *decoder, AVFrame *frame, void *u1, v
static int __rtp_decode(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
struct transcode_packet *packet, struct media_packet *mp)
{
int ret = decoder_input_data_ptime(ch->decoder, packet->payload, packet->ts, &mp->ptime,
ch->handler->packet_decoded,
ch, mp);
mp->ssrc_out->parent->seq_diff--;
int ret = 0;
if (packet)
ret = decoder_input_data_ptime(ch->decoder, packet->payload, packet->ts, &mp->ptime,
ch->handler->packet_decoded,
ch, mp);
__buffer_delay_seq(input_ch->handler->delay_buffer, mp, -1);
return ret;
}
static int packet_decode(struct codec_ssrc_handler *ch, struct codec_ssrc_handler *input_ch,
@ -3486,12 +3509,8 @@ static int packet_decode(struct codec_ssrc_handler *ch, struct codec_ssrc_handle
ilogs(transcoding, LOG_DEBUG, "Resetting decoder DTMF state due to TS discrepancy");
input_ch->dtmf_start_ts = 0;
}
else {
ilogs(transcoding, LOG_DEBUG, "Decoder is in DTMF state, discaring codec packet");
if (mp->ssrc_out)
mp->ssrc_out->parent->seq_diff--;
goto out;
}
else
packet = NULL;
}
}

Loading…
Cancel
Save