]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Add flags to chanspy audiohook so that audio stays in sync.
authorMark Michelson <mmichelson@digium.com>
Thu, 28 May 2009 14:49:13 +0000 (14:49 +0000)
committerMark Michelson <mmichelson@digium.com>
Thu, 28 May 2009 14:49:13 +0000 (14:49 +0000)
There are two flags being added to the chanspy audiohook here. One
is the pre-existing AST_AUDIOHOOK_TRIGGER_SYNC flag. With this set,
we ensure that the read and write slinfactories on the audiohook do
not skew beyond a certain tolerance.

In addition, there is a new audiohook flag added here,
AST_AUDIOHOOK_SMALL_QUEUE. With this flag set, we do not allow for
a slinfactory to build up a substantial amount of audio before
flushing it. For this particular issue, this means that the person
spying on the call will hear the conversations in real time with very
little delay in the audio.

(closes issue #13745)
Reported by: geoffs
Patches:
      13745.patch uploaded by mmichelson (license 60)
Tested by: snblitz

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@197537 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_chanspy.c
include/asterisk/audiohook.h
main/audiohook.c

index 18e4972a5e1a5d72e31679a7b8784348a225178c..d95991f8ae226dd1d0ca3bed87456d27c3abbb5d 100644 (file)
@@ -215,6 +215,8 @@ static int start_spying(struct ast_channel *chan, const char *spychan_name, stru
 
        ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, chan->name);
 
+       ast_set_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC | AST_AUDIOHOOK_SMALL_QUEUE);
+
        res = ast_audiohook_attach(chan, audiohook);
 
        if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) { 
index 8839cbde461b764f6478943aaa703c23b4f7782c..5d4ec996c5ed76525cbd8a66e28977b4c0ee3e44 100644 (file)
@@ -54,6 +54,10 @@ enum ast_audiohook_flags {
        AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), /*!< Audiohook wants to be triggered when writing audio out */
        AST_AUDIOHOOK_WANTS_DTMF = (1 << 1),    /*!< Audiohook also wants to receive DTMF frames */
        AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2),  /*!< Audiohook wants to be triggered when both sides have combined audio available */
+       /*! Audiohooks with this flag set will not allow for a large amount of samples to build up on its
+        * slinfactories. We will flush the factories if they contain too many samples.
+        */
+       AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3),
 };
 
 #define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*< Tolerance in milliseconds for audiohooks synchronization */
index d055a73f1939f34bdba1f6b87692ad5e2fdee305..ec6f0f316edfb4c7ea966b4e5f97fd2b1ea1ecaa 100644 (file)
@@ -130,6 +130,7 @@ int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohoo
        struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
        struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory);
        struct timeval *time = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *time;
+       int our_factory_samples;
        int our_factory_ms;
        int other_factory_samples;
        int other_factory_ms;
@@ -137,7 +138,8 @@ int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohoo
        /* Update last feeding time to be current */
        *time = ast_tvnow();
 
-       our_factory_ms = ast_tvdiff_ms(*time, previous_time) + (ast_slinfactory_available(factory) / 8);
+       our_factory_samples = ast_slinfactory_available(factory);
+       our_factory_ms = ast_tvdiff_ms(*time, previous_time) + (our_factory_samples / 8);
        other_factory_samples = ast_slinfactory_available(other_factory);
        other_factory_ms = other_factory_samples / 8;
 
@@ -149,6 +151,14 @@ int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohoo
                ast_slinfactory_flush(other_factory);
        }
 
+       if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && (our_factory_samples > 640 || other_factory_samples > 640)) {
+               if (option_debug) {
+                       ast_log(LOG_DEBUG, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
+               }
+               ast_slinfactory_flush(factory);
+               ast_slinfactory_flush(other_factory);
+       }
+
        /* Write frame out to respective factory */
        ast_slinfactory_feed(factory, frame);