|
|
|
@ -139,6 +139,12 @@ static void __handler_shutdown(struct codec_handler *handler) { |
|
|
|
handler->output_handler = handler; // reset to default |
|
|
|
handler->dtmf_payload_type = -1; |
|
|
|
handler->pcm_dtmf_detect = 0; |
|
|
|
|
|
|
|
if (handler->stats_entry) { |
|
|
|
g_atomic_int_add(&handler->stats_entry->num_transcoders, -1); |
|
|
|
handler->stats_entry = NULL; |
|
|
|
free(handler->stats_chain); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void __codec_handler_free(void *pp) { |
|
|
|
@ -240,6 +246,30 @@ reset: |
|
|
|
|
|
|
|
handler->ssrc_hash = create_ssrc_hash_full(__ssrc_handler_transcode_new, handler); |
|
|
|
|
|
|
|
// stats entry |
|
|
|
if (asprintf(&handler->stats_chain, STR_FORMAT " -> " STR_FORMAT, |
|
|
|
STR_FMT(&handler->source_pt.encoding_with_params), |
|
|
|
STR_FMT(&dest->encoding_with_params)) < 0) |
|
|
|
ilog(LOG_ERR, "asprintf error"); |
|
|
|
else { |
|
|
|
mutex_lock(&rtpe_codec_stats_lock); |
|
|
|
struct codec_stats *stats_entry = |
|
|
|
g_hash_table_lookup(rtpe_codec_stats, handler->stats_chain); |
|
|
|
if (!stats_entry) { |
|
|
|
stats_entry = g_slice_alloc0(sizeof(*stats_entry)); |
|
|
|
stats_entry->chain = strdup(handler->stats_chain); |
|
|
|
g_hash_table_insert(rtpe_codec_stats, stats_entry->chain, stats_entry); |
|
|
|
if (asprintf(&stats_entry->chain_brief, STR_FORMAT "_" STR_FORMAT, |
|
|
|
STR_FMT(&handler->source_pt.encoding_with_params), |
|
|
|
STR_FMT(&dest->encoding_with_params)) < 0) |
|
|
|
stats_entry->chain_brief = "xxx"; |
|
|
|
} |
|
|
|
handler->stats_entry = stats_entry; |
|
|
|
mutex_unlock(&rtpe_codec_stats_lock); |
|
|
|
|
|
|
|
g_atomic_int_inc(&stats_entry->num_transcoders); |
|
|
|
} |
|
|
|
|
|
|
|
check_output:; |
|
|
|
// check if we have multiple decoders transcoding to the same output PT |
|
|
|
struct codec_handler *output_handler = NULL; |
|
|
|
@ -1903,6 +1933,13 @@ static int packet_decoded_common(decoder_t *decoder, AVFrame *frame, void *u1, v |
|
|
|
ch = new_ch; |
|
|
|
} |
|
|
|
|
|
|
|
struct codec_handler *h = ch->handler; |
|
|
|
if (h->stats_entry) { |
|
|
|
int idx = rtpe_now.tv_sec & 1; |
|
|
|
atomic64_add(&h->stats_entry->pcm_samples[idx], frame->nb_samples); |
|
|
|
atomic64_add(&h->stats_entry->pcm_samples[2], frame->nb_samples); |
|
|
|
} |
|
|
|
|
|
|
|
if (ch->skip_pts) { |
|
|
|
if (frame->nb_samples <= 0) |
|
|
|
; |
|
|
|
@ -1923,7 +1960,7 @@ static int packet_decoded_common(decoder_t *decoder, AVFrame *frame, void *u1, v |
|
|
|
|
|
|
|
__dtmf_detect(ch, frame); |
|
|
|
|
|
|
|
input_func(ch->encoder, frame, ch->handler->packet_encoded, ch, mp); |
|
|
|
input_func(ch->encoder, frame, h->packet_encoded, ch, mp); |
|
|
|
|
|
|
|
discard: |
|
|
|
av_frame_free(&frame); |
|
|
|
@ -1962,6 +1999,25 @@ static int handler_func_transcode(struct codec_handler *h, struct media_packet * |
|
|
|
ntohl(mp->rtp->ssrc), mp->rtp->m_pt, ntohs(mp->rtp->seq_num), |
|
|
|
ntohl(mp->rtp->timestamp), mp->payload.len); |
|
|
|
|
|
|
|
if (h->stats_entry) { |
|
|
|
unsigned int idx = rtpe_now.tv_sec & 1; |
|
|
|
int last_tv_sec = g_atomic_int_get(&h->stats_entry->last_tv_sec[idx]); |
|
|
|
if (last_tv_sec != (int) rtpe_now.tv_sec) { |
|
|
|
if (g_atomic_int_compare_and_exchange(&h->stats_entry->last_tv_sec[idx], |
|
|
|
last_tv_sec, rtpe_now.tv_sec)) |
|
|
|
{ |
|
|
|
// new second - zero out stats. slight race condition here |
|
|
|
atomic64_set(&h->stats_entry->packets_input[idx], 0); |
|
|
|
atomic64_set(&h->stats_entry->bytes_input[idx], 0); |
|
|
|
atomic64_set(&h->stats_entry->pcm_samples[idx], 0); |
|
|
|
} |
|
|
|
} |
|
|
|
atomic64_inc(&h->stats_entry->packets_input[idx]); |
|
|
|
atomic64_add(&h->stats_entry->bytes_input[idx], mp->payload.len); |
|
|
|
atomic64_inc(&h->stats_entry->packets_input[2]); |
|
|
|
atomic64_add(&h->stats_entry->bytes_input[2], mp->payload.len); |
|
|
|
} |
|
|
|
|
|
|
|
struct transcode_packet *packet = g_slice_alloc0(sizeof(*packet)); |
|
|
|
packet->func = packet_decode; |
|
|
|
packet->rtp = *mp->rtp; |
|
|
|
|