[Asterisk-code-review] app chanspy: reduce audio loss on the spying channel. (asterisk[master])

Anonymous Coward asteriskteam at digium.com
Thu Apr 28 17:45:58 CDT 2016


Anonymous Coward #1000019 has submitted this change and it was merged.

Change subject: app_chanspy: reduce audio loss on the spying channel.
......................................................................


app_chanspy: reduce audio loss on the spying channel.

ChanSpy was creating its audiohook with the flags AST_AUDIOHOOK_TRIGGER_SYNC
and AST_AUDIOHOOK_SMALL_QUEUE, which caused audio frames to be lost when
queues grow too large or when read and write queues go out of sync.
Now these flags are set conditionally:
- AST_AUDIOHOOK_TRIGGER_SYNC is not set if the option "o" is set
- a new option "l" is created: if set, AST_AUDIOHOOK_SMALL_QUEUE will not
be set on the audiohook

ASTERISK-25866

Change-Id: I9c7652f41d9fa72c8691e4e70ec4fd16b047a4dd
---
M CHANGES
M apps/app_chanspy.c
M main/audiohook.c
3 files changed, 36 insertions(+), 8 deletions(-)

Approvals:
  Mark Michelson: Looks good to me, approved
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, but someone else must approve



diff --git a/CHANGES b/CHANGES
index e7f0656..56e6315 100644
--- a/CHANGES
+++ b/CHANGES
@@ -31,6 +31,13 @@
  * A new application in Asterisk, this will join the calling channel
    to an existing bridge containing the named channel prefix.
 
+ChanSpy
+------------------
+ * Added the 'l' option, which forces ChanSpy's audiohook to use a long queue
+   to store the audio frames. This option is useful if audio loss is
+   experienced when using ChanSpy, but may introduce some delay in the audio
+   feed on the listening channel.
+
 ConfBridge
 ------------------
  * Added the ability to pass options to MixMonitor when recording is used with
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 5dbb0b8..400eed1 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -117,6 +117,10 @@
 						either a single group or a colon-delimited list of groups, such
 						as <literal>sales:support:accounting</literal>.</para></note>
 					</option>
+					<option name="l">
+						<para>Allow usage of a long queue to store audio frames.</para>
+						<note><para>This may introduce some delay in the received audio feed, but will improve the audio quality.</para></note>
+					</option>
 					<option name="n" argsep="@">
 						<para>Say the name of the person being spied on if that person has recorded
 						his/her name. If a context is specified, then that voicemail context will
@@ -262,6 +266,10 @@
 						either a single group or a colon-delimited list of groups, such
 						as <literal>sales:support:accounting</literal>.</para></note>
 					</option>
+					<option name="l">
+						<para>Allow usage of a long queue to store audio frames.</para>
+						<note><para>This may introduce some delay in the received audio feed, but will improve the audio quality.</para></note>
+					</option>
 					<option name="n" argsep="@">
 						<para>Say the name of the person being spied on if that person has recorded
 						his/her name. If a context is specified, then that voicemail context will
@@ -386,6 +394,7 @@
 	OPTION_STOP              = (1 << 17),
 	OPTION_EXITONHANGUP      = (1 << 18),   /* Hang up when the spied-on channel hangs up. */
 	OPTION_UNIQUEID          = (1 << 19),	/* The chanprefix is a channel uniqueid or fully specified channel name. */
+	OPTION_LONG_QUEUE        = (1 << 20),	/* Allow usage of a long queue to store audio frames. */
 };
 
 enum {
@@ -407,6 +416,7 @@
 	AST_APP_OPTION_ARG('e', OPTION_ENFORCED, OPT_ARG_ENFORCED),
 	AST_APP_OPTION('E', OPTION_EXITONHANGUP),
 	AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
+	AST_APP_OPTION('l', OPTION_LONG_QUEUE),
 	AST_APP_OPTION_ARG('n', OPTION_NAME, OPT_ARG_NAME),
 	AST_APP_OPTION('o', OPTION_READONLY),
 	AST_APP_OPTION('q', OPTION_QUIET),
@@ -496,11 +506,17 @@
 	.generate = spy_generate,
 };
 
-static int start_spying(struct ast_autochan *autochan, const char *spychan_name, struct ast_audiohook *audiohook)
+static int start_spying(struct ast_autochan *autochan, const char *spychan_name, struct ast_audiohook *audiohook, struct ast_flags *flags)
 {
 	ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, ast_channel_name(autochan->chan));
-
-	ast_set_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC | AST_AUDIOHOOK_SMALL_QUEUE);
+	if(!ast_test_flag(flags, OPTION_READONLY)) {
+		ast_set_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC | AST_AUDIOHOOK_MUTE_WRITE);
+	}
+	if(ast_test_flag(flags, OPTION_LONG_QUEUE)) {
+		ast_debug(9, "Using a long queue to store audio frames in spy audiohook\n");
+	} else {
+		ast_set_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE);
+	}
 	return ast_audiohook_attach(autochan->chan, audiohook);
 }
 
@@ -581,7 +597,7 @@
 
 static int attach_barge(struct ast_autochan *spyee_autochan,
 	struct ast_autochan **spyee_bridge_autochan, struct ast_audiohook *bridge_whisper_audiohook,
-	const char *spyer_name, const char *name)
+	const char *spyer_name, const char *name, struct ast_flags *flags)
 {
 	int retval = 0;
 	struct ast_autochan *internal_bridge_autochan;
@@ -599,7 +615,7 @@
 	}
 
 	ast_autochan_channel_lock(internal_bridge_autochan);
-	if (start_spying(internal_bridge_autochan, spyer_name, bridge_whisper_audiohook)) {
+	if (start_spying(internal_bridge_autochan, spyer_name, bridge_whisper_audiohook, flags)) {
 		ast_log(LOG_WARNING, "Unable to attach barge audiohook on spyee '%s'. Barge mode disabled.\n", name);
 		retval = -1;
 	}
@@ -647,7 +663,7 @@
 	*/
 	ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy", 0);
 
-	if (start_spying(spyee_autochan, spyer_name, &csth.spy_audiohook)) {
+	if (start_spying(spyee_autochan, spyer_name, &csth.spy_audiohook, flags)) {
 		ast_audiohook_destroy(&csth.spy_audiohook);
 		return 0;
 	}
@@ -658,7 +674,7 @@
 		*/
 		ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy", 0);
 
-		if (start_spying(spyee_autochan, spyer_name, &csth.whisper_audiohook)) {
+		if (start_spying(spyee_autochan, spyer_name, &csth.whisper_audiohook, flags)) {
 			ast_log(LOG_WARNING, "Unable to attach whisper audiohook to spyee %s. Whisper mode disabled!\n", name);
 		}
 	}
@@ -710,7 +726,7 @@
 			 * be attached and we'll need to continue attempting to attach the barge
 			 * audio hook. */
 			if (!bridge_connected && attach_barge(spyee_autochan, &spyee_bridge_autochan,
-					&csth.bridge_whisper_audiohook, spyer_name, name) == 0) {
+					&csth.bridge_whisper_audiohook, spyer_name, name, flags) == 0) {
 				bridge_connected = 1;
 			}
 
diff --git a/main/audiohook.c b/main/audiohook.c
index e308913..4a73fbd 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -45,6 +45,7 @@
 
 #define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*!< Tolerance in milliseconds for audiohooks synchronization */
 #define AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE 100 /*!< When small queue is enabled, this is the maximum amount of audio that can remain queued at a time. */
+#define AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE 500 /*!< Otheriwise we still don't want the queue to grow indefinitely */
 
 #define DEFAULT_INTERNAL_SAMPLE_RATE 8000
 
@@ -192,6 +193,10 @@
 		ast_debug(1, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
 		ast_slinfactory_flush(factory);
 		ast_slinfactory_flush(other_factory);
+	} else if ((our_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE) || (other_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE)) {
+		ast_debug(1, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
+		ast_slinfactory_flush(factory);
+		ast_slinfactory_flush(other_factory);
 	}
 
 	/* swap frame data for zeros if mute is required */

-- 
To view, visit https://gerrit.asterisk.org/2520
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I9c7652f41d9fa72c8691e4e70ec4fd16b047a4dd
Gerrit-PatchSet: 3
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Jean Aunis - Prescom <jean.aunis at prescom.fr>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Jean Aunis - Prescom <jean.aunis at prescom.fr>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>



More information about the asterisk-code-review mailing list