"\tIt does not indicate anything about your configuration.\n");
}
- ast_cli(a->fd, "%8s %-5s %-12s %-16s %s\n","ID","TYPE","NAME","FORMAT","DESCRIPTION");
+ ast_cli(a->fd, "%8s %-5s %-12s %-16s %7s %s\n","ID","TYPE","NAME","FORMAT","QUALITY", "DESCRIPTION");
ast_cli(a->fd, "------------------------------------------------------------------------------------------------\n");
ao2_rdlock(codecs);
}
}
- ast_cli(a->fd, "%8u %-5s %-12s %-16s (%s)\n",
+ ast_cli(a->fd, "%8u %-5s %-12s %-16s %7d (%s)\n",
codec->external.id,
ast_codec_media_type2str(codec->external.type),
codec->external.name,
S_OR(codec->format_name, "no cached format"),
+ codec->external.quality,
codec->external.description);
}
.minimum_bytes = 20,
.samples_count = g723_samples,
.get_length = g723_length,
+ .quality = 20,
};
static int codec2_samples(struct ast_frame *frame)
.samples_count = ulaw_samples,
.get_length = ulaw_length,
.smooth = 1,
+ .quality = 100, /* We are the gold standard. */
};
static struct ast_codec alaw = {
.samples_count = ulaw_samples,
.get_length = ulaw_length,
.smooth = 1,
+ .quality = 100, /* Just as good as ulaw */
};
static int gsm_samples(struct ast_frame *frame)
.samples_count = gsm_samples,
.get_length = gsm_length,
.smooth = 1,
+ .quality = 60,
};
static int g726_samples(struct ast_frame *frame)
.samples_count = g726_samples,
.get_length = g726_length,
.smooth = 1,
+ .quality = 85,
};
static struct ast_codec g726aal2 = {
.samples_count = g726_samples,
.get_length = g726_length,
.smooth = 1,
+ .quality = 85,
};
static struct ast_codec adpcm = {
.samples_count = g726_samples,
.get_length = g726_length,
.smooth = 1,
+ .quality = 80,
};
static int slin_samples(struct ast_frame *frame)
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 115, /* Better than ulaw */
};
static struct ast_codec slin12 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 116,
};
static struct ast_codec slin16 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 117,
};
static struct ast_codec slin24 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 118,
};
static struct ast_codec slin32 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 119,
};
static struct ast_codec slin44 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 120,
};
static struct ast_codec slin48 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 121,
};
static struct ast_codec slin96 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 122,
};
static struct ast_codec slin192 = {
.get_length = slin_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
+ .quality = 123,
};
static int lpc10_samples(struct ast_frame *frame)
.minimum_bytes = 7,
.samples_count = lpc10_samples,
.smooth = 1,
+ .quality = 25,
};
static int g729_samples(struct ast_frame *frame)
.get_length = g729_length,
.smooth = 1,
.smoother_flags = AST_SMOOTHER_FLAG_G729,
+ .quality = 20,
};
static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
.default_ms = 20,
.minimum_bytes = 10,
.samples_count = speex8_samples,
+ .quality = 40,
};
static int speex16_samples(struct ast_frame *frame)
.default_ms = 20,
.minimum_bytes = 10,
.samples_count = speex16_samples,
+ .quality = 40,
};
static int speex32_samples(struct ast_frame *frame)
.default_ms = 20,
.minimum_bytes = 10,
.samples_count = speex32_samples,
+ .quality = 40,
};
static int ilbc_samples(struct ast_frame *frame)
.minimum_bytes = 38,
.samples_count = ilbc_samples,
.smooth = 0,
+ .quality = 45,
};
static struct ast_codec g722 = {
.samples_count = g726_samples,
.get_length = g726_length,
.smooth = 1,
+ .quality = 110, /* In theory, better than ulaw */
};
static int siren7_samples(struct ast_frame *frame)
.minimum_bytes = 80,
.samples_count = siren7_samples,
.get_length = siren7_length,
+ .quality = 85,
};
static int siren14_samples(struct ast_frame *frame)
.minimum_bytes = 120,
.samples_count = siren14_samples,
.get_length = siren14_length,
+ .quality = 90,
};
static int g719_samples(struct ast_frame *frame)
.minimum_bytes = 160,
.samples_count = g719_samples,
.get_length = g719_length,
+ .quality = 95,
};
static int opus_samples(struct ast_frame *frame)
.default_ms = 20,
.samples_count = opus_samples,
.minimum_bytes = 10,
+ .quality = 50,
};
static struct ast_codec jpeg = {
.maximum_ms = 100,
.default_ms = 20,
.minimum_bytes = 160,
- .samples_count = silk_samples
+ .samples_count = silk_samples,
};
static struct ast_codec silk12 = {
beststeps = matrix_get(x, y)->multistep;
} else if (matrix_get(x, y)->table_cost == besttablecost
&& matrix_get(x, y)->multistep == beststeps) {
+ int replace = 0;
unsigned int gap_selected = format_sample_rate_absdiff(best, bestdst);
unsigned int gap_current = format_sample_rate_absdiff(src, dst);
if (gap_current < gap_selected) {
/* better than what we have so far */
+ replace = 1;
+ } else if (gap_current == gap_selected) {
+ int src_quality, best_quality;
+ struct ast_codec *src_codec, *best_codec;
+
+ src_codec = ast_format_get_codec(src);
+ best_codec = ast_format_get_codec(best);
+ src_quality = src_codec->quality;
+ best_quality = best_codec->quality;
+
+ ao2_cleanup(src_codec);
+ ao2_cleanup(best_codec);
+
+ /* We have a tie, so choose the format with the higher quality, if they differ. */
+ if (src_quality > best_quality) {
+ /* Better than what we had before. */
+ replace = 1;
+ ast_debug(2, "Tiebreaker: preferring format %s (%d) to %s (%d)\n", ast_format_get_name(src), src_quality,
+ ast_format_get_name(best), best_quality);
+ } else {
+ /* This isn't necessarily indicative of a problem, but in reality this shouldn't really happen, unless
+ * there are 2 formats that are basically the same. */
+ ast_debug(1, "Completely ambiguous tie between formats %s and %s (quality %d): sticking with %s, but this is arbitrary\n",
+ ast_format_get_name(src), ast_format_get_name(best), best_quality, ast_format_get_name(best));
+ }
+ }
+ if (replace) {
ao2_replace(best, src);
ao2_replace(bestdst, dst);
besttablecost = matrix_get(x, y)->table_cost;