Browse Source

MT#56008 support variable clock rate factors

This makes it possible to have codecs running at variable clock rates
that differ from their RTP clock rates.

Change-Id: Ia2f5effb82eefe8c3028573ba0a6697da28473b1
pull/1579/head
Richard Fuchs 3 years ago
parent
commit
0114728f47
5 changed files with 31 additions and 25 deletions
  1. +5
    -5
      daemon/codec.c
  2. +1
    -1
      daemon/media_player.c
  3. +21
    -17
      lib/codeclib.c
  4. +3
    -1
      lib/codeclib.h
  5. +1
    -1
      recording-daemon/decoder.c

+ 5
- 5
daemon/codec.c View File

@ -1899,7 +1899,7 @@ static int codec_add_dtmf_packet(struct codec_ssrc_handler *ch, struct codec_ssr
ch->last_dtmf_event_ts = 0; // last DTMF event duration ch->last_dtmf_event_ts = 0; // last DTMF event duration
} }
unsigned long ts = fraction_divl(output_ch->encoder->next_pts, &output_ch->encoder->def->clockrate_fact);
unsigned long ts = fraction_divl(output_ch->encoder->next_pts, &output_ch->encoder->clockrate_fact);
// roll back TS to start of event // roll back TS to start of event
ts -= ch->last_dtmf_event_ts; ts -= ch->last_dtmf_event_ts;
// adjust to output RTP TS // adjust to output RTP TS
@ -1924,8 +1924,8 @@ static int codec_add_dtmf_packet(struct codec_ssrc_handler *ch, struct codec_ssr
ts_delay = duration - ch->dtmf_first_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 = fraction_multl(ts + duration, &output_ch->encoder->def->clockrate_fact);
output_ch->encoder->packet_pts += fraction_multl(duration - ch->last_dtmf_event_ts, &output_ch->encoder->def->clockrate_fact);
output_ch->encoder->next_pts = fraction_multl(ts + duration, &output_ch->encoder->clockrate_fact);
output_ch->encoder->packet_pts += fraction_multl(duration - ch->last_dtmf_event_ts, &output_ch->encoder->clockrate_fact);
ch->last_dtmf_event_ts = duration; ch->last_dtmf_event_ts = duration;
} }
payload_type = h->dtmf_payload_type; payload_type = h->dtmf_payload_type;
@ -3412,7 +3412,7 @@ static struct ssrc_entry *__ssrc_handler_transcode_new(void *p) {
ch->bitrate = h->dest_pt.bitrate ? : h->dest_pt.codec_def->default_bitrate; ch->bitrate = h->dest_pt.bitrate ? : h->dest_pt.codec_def->default_bitrate;
format_t enc_format = { format_t enc_format = {
.clockrate = fraction_mult(h->dest_pt.clock_rate, &h->dest_pt.codec_def->clockrate_fact),
.clockrate = h->dest_pt.clock_rate,
.channels = h->dest_pt.channels, .channels = h->dest_pt.channels,
.format = -1, .format = -1,
}; };
@ -3569,7 +3569,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) {
memcpy(send_buf, buf, pkt_len); memcpy(send_buf, buf, pkt_len);
} }
__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
+ fraction_divl(enc->avpkt->pts, &enc->def->clockrate_fact),
+ fraction_divl(enc->avpkt->pts, &enc->clockrate_fact),
ch->rtp_mark ? 1 : 0, -1, 0, ch->rtp_mark ? 1 : 0, -1, 0,
payload_type, 0); payload_type, 0);
mp->ssrc_out->parent->seq_diff++; mp->ssrc_out->parent->seq_diff++;


+ 1
- 1
daemon/media_player.c View File

@ -306,7 +306,7 @@ found:
// that has passed // that has passed
if (mp->sync_ts_tv.tv_sec) { if (mp->sync_ts_tv.tv_sec) {
long long ts_diff_us = timeval_diff(&rtpe_now, &mp->sync_ts_tv); long long ts_diff_us = timeval_diff(&rtpe_now, &mp->sync_ts_tv);
mp->sync_ts += fraction_divl(ts_diff_us * dst_pt->clock_rate / 1000000, &dst_pt->codec_def->clockrate_fact);
mp->sync_ts += fraction_divl(ts_diff_us * dst_pt->clock_rate / 1000000, &dst_pt->codec_def->default_clockrate_fact);
} }
// if we already have a handler, see if anything needs changing // if we already have a handler, see if anything needs changing


+ 21
- 17
lib/codeclib.c View File

@ -259,7 +259,7 @@ static codec_def_t __codec_defs[] = {
{ {
.rtpname = "G722", .rtpname = "G722",
.avcodec_id = AV_CODEC_ID_ADPCM_G722, .avcodec_id = AV_CODEC_ID_ADPCM_G722,
.clockrate_fact = {2,1},
.default_clockrate_fact = {2,1},
.default_clockrate = 8000, .default_clockrate = 8000,
.default_channels = 1, .default_channels = 1,
.default_ptime = 20, .default_ptime = 20,
@ -415,7 +415,7 @@ static codec_def_t __codec_defs[] = {
{ {
.rtpname = "EVS", .rtpname = "EVS",
.avcodec_id = -1, .avcodec_id = -1,
.clockrate_fact = {3,1},
.default_clockrate_fact = {3,1},
.default_clockrate = 16000, .default_clockrate = 16000,
.default_channels = 1, .default_channels = 1,
.default_ptime = 20, .default_ptime = 20,
@ -749,11 +749,11 @@ decoder_t *decoder_new_fmtp(const codec_def_t *def, int clockrate, int channels,
if (!def->codec_type) if (!def->codec_type)
goto err; goto err;
clockrate = fraction_mult(clockrate, &def->clockrate_fact);
ret = g_slice_alloc0(sizeof(*ret)); ret = g_slice_alloc0(sizeof(*ret));
ret->def = def; ret->def = def;
ret->clockrate_fact = def->default_clockrate_fact;
clockrate = fraction_mult(clockrate, &ret->clockrate_fact);
format_init(&ret->in_format); format_init(&ret->in_format);
ret->in_format.channels = channels; ret->in_format.channels = channels;
ret->in_format.clockrate = clockrate; ret->in_format.clockrate = clockrate;
@ -976,7 +976,7 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t
if (!data && (!dec->dtx.do_dtx || !ptime)) if (!data && (!dec->dtx.do_dtx || !ptime))
return 0; return 0;
ts = fraction_mult(ts, &dec->def->clockrate_fact);
ts = fraction_mult(ts, &dec->clockrate_fact);
cdbg("%p dec pts %llu rtp_ts %llu incoming ts %lu", dec, (unsigned long long) dec->pts, cdbg("%p dec pts %llu rtp_ts %llu incoming ts %lu", dec, (unsigned long long) dec->pts,
(unsigned long long) dec->rtp_ts, (unsigned long) ts); (unsigned long long) dec->rtp_ts, (unsigned long) ts);
@ -1136,10 +1136,10 @@ void codeclib_init(int print) {
} }
// init undefined member vars // init undefined member vars
if (!def->clockrate_fact.mult)
def->clockrate_fact.mult = 1;
if (!def->clockrate_fact.div)
def->clockrate_fact.div = 1;
if (!def->default_clockrate_fact.mult)
def->default_clockrate_fact.mult = 1;
if (!def->default_clockrate_fact.div)
def->default_clockrate_fact.div = 1;
if (!def->default_ptime) if (!def->default_ptime)
def->default_ptime = -1; def->default_ptime = -1;
if (!def->default_clockrate) if (!def->default_clockrate)
@ -1417,7 +1417,7 @@ int encoder_config(encoder_t *enc, const codec_def_t *def, int bitrate, int ptim
} }
int encoder_config_fmtp(encoder_t *enc, const codec_def_t *def, int bitrate, int ptime, int encoder_config_fmtp(encoder_t *enc, const codec_def_t *def, int bitrate, int ptime,
const format_t *requested_format, format_t *actual_format,
const format_t *requested_format_p, format_t *actual_format,
struct rtp_codec_format *fmtp, const str *fmtp_string, struct rtp_codec_format *fmtp, const str *fmtp_string,
const str *extra_opts) const str *extra_opts)
{ {
@ -1427,8 +1427,12 @@ int encoder_config_fmtp(encoder_t *enc, const codec_def_t *def, int bitrate, int
if (!def->codec_type) if (!def->codec_type)
goto err; goto err;
enc->clockrate_fact = def->default_clockrate_fact;
format_t requested_format = *requested_format_p;
requested_format.clockrate = fraction_mult(requested_format.clockrate, &enc->clockrate_fact);
// anything to do? // anything to do?
if (G_LIKELY(format_eq(requested_format, &enc->requested_format)))
if (G_LIKELY(format_eq(&requested_format, &enc->requested_format)))
goto done; goto done;
encoder_close(enc); encoder_close(enc);
@ -1436,9 +1440,9 @@ int encoder_config_fmtp(encoder_t *enc, const codec_def_t *def, int bitrate, int
if (ptime <= 0) if (ptime <= 0)
ptime = 20; ptime = 20;
enc->requested_format = *requested_format;
enc->requested_format = requested_format;
enc->def = def; enc->def = def;
enc->ptime = fraction_div(ptime, &def->clockrate_fact);
enc->ptime = fraction_div(ptime, &enc->clockrate_fact);
enc->bitrate = bitrate; enc->bitrate = bitrate;
err = "failed to parse \"fmtp\""; err = "failed to parse \"fmtp\"";
@ -1673,7 +1677,7 @@ static int packetizer_samplestream(AVPacket *pkt, GString *buf, str *input_outpu
g_string_append_len(buf, (char *) pkt->data + input_output->len, g_string_append_len(buf, (char *) pkt->data + input_output->len,
pkt->size - input_output->len); pkt->size - input_output->len);
enc->packet_pts = pkt->pts + input_output->len enc->packet_pts = pkt->pts + input_output->len
* (fraction_mult(enc->def->bits_per_sample, &enc->def->clockrate_fact) / 8);
* (fraction_mult(enc->def->bits_per_sample, &enc->clockrate_fact) / 8);
} }
return buf->len >= input_output->len ? 1 : 0; return buf->len >= input_output->len ? 1 : 0;
} }
@ -1689,7 +1693,7 @@ static int packetizer_samplestream(AVPacket *pkt, GString *buf, str *input_outpu
// adjust output pts // adjust output pts
enc->avpkt->pts = enc->packet_pts; enc->avpkt->pts = enc->packet_pts;
enc->packet_pts += input_output->len enc->packet_pts += input_output->len
* fraction_mult(enc->def->bits_per_sample, &enc->def->clockrate_fact) / 8;
* fraction_mult(enc->def->bits_per_sample, &enc->clockrate_fact) / 8;
return buf->len >= input_output->len ? 1 : 0; return buf->len >= input_output->len ? 1 : 0;
} }
@ -3194,7 +3198,7 @@ static const char *evs_decoder_init(decoder_t *dec, const str *extra_opts) {
dec->u.evs = g_slice_alloc0(evs_decoder_size); dec->u.evs = g_slice_alloc0(evs_decoder_size);
if (dec->in_format.clockrate != 48000) if (dec->in_format.clockrate != 48000)
ilog(LOG_WARN, "EVS: invalid decoder clock rate (%i) requested", ilog(LOG_WARN, "EVS: invalid decoder clock rate (%i) requested",
fraction_div(dec->in_format.clockrate, &dec->def->clockrate_fact));
fraction_div(dec->in_format.clockrate, &dec->clockrate_fact));
if (dec->in_format.channels != 1) if (dec->in_format.channels != 1)
ilog(LOG_WARN, "EVS: %i-channel EVS is not supported", ilog(LOG_WARN, "EVS: %i-channel EVS is not supported",
dec->in_format.channels); dec->in_format.channels);
@ -3440,7 +3444,7 @@ static const char *evs_encoder_init(encoder_t *enc, const str *extra_opts) {
enc->u.evs.ind_list = g_slice_alloc(evs_encoder_ind_list_size); enc->u.evs.ind_list = g_slice_alloc(evs_encoder_ind_list_size);
if (enc->requested_format.clockrate != 48000) if (enc->requested_format.clockrate != 48000)
ilog(LOG_WARN, "EVS: invalid encoder clock rate (%i) requested", ilog(LOG_WARN, "EVS: invalid encoder clock rate (%i) requested",
fraction_div(enc->requested_format.clockrate, &enc->def->clockrate_fact));
fraction_div(enc->requested_format.clockrate, &enc->clockrate_fact));
if (enc->requested_format.channels != 1) if (enc->requested_format.channels != 1)
ilog(LOG_WARN, "EVS: %i-channel EVS is not supported", ilog(LOG_WARN, "EVS: %i-channel EVS is not supported",
enc->requested_format.channels); enc->requested_format.channels);


+ 3
- 1
lib/codeclib.h View File

@ -160,7 +160,7 @@ INLINE long fraction_divl(long a, const struct fraction *f) {
struct codec_def_s { struct codec_def_s {
const char * const rtpname; const char * const rtpname;
struct fraction clockrate_fact;
struct fraction default_clockrate_fact;
const int avcodec_id; const int avcodec_id;
const char * const avcodec_name_enc; const char * const avcodec_name_enc;
const char * const avcodec_name_dec; const char * const avcodec_name_dec;
@ -236,6 +236,7 @@ struct dtx_method_s {
struct decoder_s { struct decoder_s {
const codec_def_t *def; const codec_def_t *def;
struct fraction clockrate_fact;
codec_options_t codec_options; codec_options_t codec_options;
union codec_format_options format_options; union codec_format_options format_options;
dtx_method_t dtx; dtx_method_t dtx;
@ -283,6 +284,7 @@ struct encoder_s {
actual_format; actual_format;
const codec_def_t *def; const codec_def_t *def;
struct fraction clockrate_fact;
codec_options_t codec_options; codec_options_t codec_options;
encoder_callback_t callback; encoder_callback_t callback;
union codec_format_options format_options; union codec_format_options format_options;


+ 1
- 1
recording-daemon/decoder.c View File

@ -62,7 +62,7 @@ decode_t *decoder_new(const char *payload_str, const char *format, int ptime, ou
// decoder_new_fmt already handles the clockrate_mult scaling // decoder_new_fmt already handles the clockrate_mult scaling
int rtp_clockrate = clockrate; int rtp_clockrate = clockrate;
clockrate = fraction_mult(clockrate, &def->clockrate_fact);
clockrate = fraction_mult(clockrate, &def->default_clockrate_fact);
// we can now config our output, which determines the sample format we convert to // we can now config our output, which determines the sample format we convert to
format_t out_format = { format_t out_format = {


Loading…
Cancel
Save