[asterisk-commits] mmichelson: branch 1.4 r264541 - in /branches/1.4: include/asterisk/ main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu May 20 10:59:47 CDT 2010
Author: mmichelson
Date: Thu May 20 10:59:44 2010
New Revision: 264541
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=264541
Log:
1.4 version of PLC fix.
Analogous to trunk revision 264452, but without the change
to chan_sip since it is not necessary in this branch.
Modified:
branches/1.4/include/asterisk/channel.h
branches/1.4/include/asterisk/options.h
branches/1.4/main/channel.c
branches/1.4/main/loader.c
Modified: branches/1.4/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/include/asterisk/channel.h?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/include/asterisk/channel.h (original)
+++ branches/1.4/include/asterisk/channel.h Thu May 20 10:59:44 2010
@@ -1467,6 +1467,12 @@
*/
char *ast_channel_reason2str(int reason);
+/*!
+ * \brief Reload genericplc configuration value from codecs.conf
+ *
+ * Implementation is in main/channel.c
+ */
+int ast_plc_reload(void);
#if defined(__cplusplus) || defined(c_plusplus)
}
Modified: branches/1.4/include/asterisk/options.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/include/asterisk/options.h?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/include/asterisk/options.h (original)
+++ branches/1.4/include/asterisk/options.h Thu May 20 10:59:44 2010
@@ -80,7 +80,9 @@
/*! Always fork, even if verbose or debug settings are non-zero */
AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
/*! Disable log/verbose output to remote consoles */
- AST_OPT_FLAG_MUTE = (1 << 22)
+ AST_OPT_FLAG_MUTE = (1 << 22),
+ /*! Generic PLC */
+ AST_OPT_FLAG_GENERIC_PLC = (1 << 23),
};
/*! These are the options that set by default when Asterisk starts */
@@ -113,6 +115,7 @@
#define ast_opt_internal_timing ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
#define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
#define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
+#define ast_opt_generic_plc ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC)
extern struct ast_flags ast_options;
Modified: branches/1.4/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/main/channel.c?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/main/channel.c (original)
+++ branches/1.4/main/channel.c Thu May 20 10:59:44 2010
@@ -2854,6 +2854,86 @@
return res;
}
+struct plc_ds {
+ /* A buffer in which to store SLIN PLC
+ * samples generated by the generic PLC
+ * functionality in plc.c
+ */
+ int16_t *samples_buf;
+ /* The current number of samples in the
+ * samples_buf
+ */
+ size_t num_samples;
+ plc_state_t plc_state;
+};
+
+static void plc_ds_destroy(void *data)
+{
+ struct plc_ds *plc = data;
+ ast_free(plc->samples_buf);
+ ast_free(plc);
+}
+
+static struct ast_datastore_info plc_ds_info = {
+ .type = "plc",
+ .destroy = plc_ds_destroy,
+};
+
+static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
+{
+ int num_new_samples = frame->samples;
+ struct plc_ds *plc = datastore->data;
+
+ /* First, we need to be sure that our buffer is large enough to accomodate
+ * the samples we need to fill in. This will likely only occur on the first
+ * frame we write.
+ */
+ if (plc->num_samples < num_new_samples) {
+ ast_free(plc->samples_buf);
+ plc->samples_buf = ast_calloc(num_new_samples, sizeof(*plc->samples_buf));
+ if (!plc->samples_buf) {
+ ast_channel_datastore_remove(chan, datastore);
+ ast_channel_datastore_free(datastore);
+ return;
+ }
+ plc->num_samples = num_new_samples;
+ }
+
+ if (frame->datalen == 0) {
+ plc_fillin(&plc->plc_state, plc->samples_buf, frame->samples);
+ frame->data = plc->samples_buf;
+ frame->datalen = num_new_samples * 2;
+ } else {
+ plc_rx(&plc->plc_state, frame->data, frame->samples);
+ }
+}
+
+static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
+{
+ struct ast_datastore *datastore;
+ struct plc_ds *plc;
+
+ datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
+ if (datastore) {
+ plc = datastore->data;
+ adjust_frame_for_plc(chan, frame, datastore);
+ return;
+ }
+
+ datastore = ast_channel_datastore_alloc(&plc_ds_info, NULL);
+ if (!datastore) {
+ return;
+ }
+ plc = ast_calloc(1, sizeof(*plc));
+ if (!plc) {
+ ast_channel_datastore_free(datastore);
+ return;
+ }
+ datastore->data = plc;
+ ast_channel_datastore_add(chan, datastore);
+ adjust_frame_for_plc(chan, frame, datastore);
+}
+
int ast_write(struct ast_channel *chan, struct ast_frame *fr)
{
int res = -1;
@@ -2962,6 +3042,10 @@
case AST_FRAME_VOICE:
if (chan->tech->write == NULL)
break; /*! \todo XXX should return 0 maybe ? */
+
+ if (ast_opt_generic_plc && fr->subclass == AST_FORMAT_SLINEAR) {
+ apply_plc(chan, fr);
+ }
/* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
if (fr->subclass == chan->rawwriteformat)
@@ -3629,10 +3713,12 @@
}
/* if the best path is not 'pass through', then
- transcoding is needed; if desired, force transcode path
- to use SLINEAR between channels, but only if there is
- no direct conversion available */
- if ((src != dst) && ast_opt_transcode_via_slin &&
+ * transcoding is needed; if desired, force transcode path
+ * to use SLINEAR between channels, but only if there is
+ * no direct conversion available. If generic PLC is
+ * desired, then transcoding via SLINEAR is a requirement
+ */
+ if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
(ast_translate_path_steps(dst, src) != 1))
dst = AST_FORMAT_SLINEAR;
if (ast_set_read_format(peer, dst) < 0) {
@@ -4932,9 +5018,26 @@
ast_moh_cleanup_ptr(chan);
}
+int ast_plc_reload(void)
+{
+ struct ast_variable *var;
+ struct ast_config *cfg = ast_config_load("codecs.conf");
+ if (!cfg)
+ return 0;
+ for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
+ if (!strcasecmp(var->name, "genericplc")) {
+ ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
+ }
+ }
+ ast_config_destroy(cfg);
+ return 0;
+}
+
void ast_channels_init(void)
{
ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
+
+ ast_plc_reload();
}
/*! \brief Print call group and pickup group ---*/
Modified: branches/1.4/main/loader.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/main/loader.c?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/main/loader.c (original)
+++ branches/1.4/main/loader.c Thu May 20 10:59:44 2010
@@ -258,6 +258,7 @@
{ "rtp", ast_rtp_reload },
{ "http", ast_http_reload },
{ "logger", logger_reload },
+ { "plc", ast_plc_reload },
{ NULL, NULL }
};
More information about the asterisk-commits
mailing list