[svn-commits] dvossel: branch 1.6.0 r214198 - in /branches/1.6.0: ./ main/channel.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Aug 26 11:40:54 CDT 2009


Author: dvossel
Date: Wed Aug 26 11:40:50 2009
New Revision: 214198

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=214198
Log:
Merged revisions 214195 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r214195 | dvossel | 2009-08-26 11:38:53 -0500 (Wed, 26 Aug 2009) | 25 lines
  
  Merged revisions 214194 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r214194 | dvossel | 2009-08-26 11:36:42 -0500 (Wed, 26 Aug 2009) | 19 lines
    
    ast_write() ignores ast_audiohook_write() results
    
    In ast_write(), if a channel has a list of audiohooks, those
    lists are written to and the resulting frame is what ast_write()
    should continue with.  The problem was the returned audiohook frame
    was not being handled at all, and the original frame passed
    into it did not contain the mixed audio, so essentially audio
    was being lost.  One result of this was chan_spy's whisper
    mode no longer worked.  To complicate the issue, frames
    passed into ast_write may either be a single frame, or a list
    of frames.  So, as the list of frames is processed in the
    audiohook_write, the returned frames had to be added to a new
    list.
    
    (closes issue #15660)
    Reported by: corruptor
    Tested by: dvossel
  ........
................

Modified:
    branches/1.6.0/   (props changed)
    branches/1.6.0/main/channel.c

Propchange: branches/1.6.0/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.0/main/channel.c
URL: http://svn.asterisk.org/svn-view/asterisk/branches/1.6.0/main/channel.c?view=diff&rev=214198&r1=214197&r2=214198
==============================================================================
--- branches/1.6.0/main/channel.c (original)
+++ branches/1.6.0/main/channel.c Wed Aug 26 11:40:50 2009
@@ -3455,13 +3455,36 @@
 		}
 
 		if (chan->audiohooks) {
-			struct ast_frame *new_frame, *cur;
-
+			struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
+
+			/* Since ast_audiohook_write may return a new frame, and the cur frame is
+			 * an item in a list of frames, create a new list adding each cur frame back to it
+			 * regardless if the cur frame changes or not. */
 			for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
 				new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
+
+				/* if this frame is different than cur, preserve the end of the list,
+				 * free the old frames, and set cur to be the new frame */
 				if (new_frame != cur) {
-					ast_frfree(new_frame);
+					/* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
+					 * isn't part of local storage, meaning if ast_audiohook_write is called multiple
+					 * times it may override the previous frame we got from it unless we dup it */
+					if ((dup = ast_frisolate(new_frame))) {
+						AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
+						ast_frfree(new_frame);
+						ast_frfree(cur);
+						cur = dup;
+					}
 				}
+
+				/* now, regardless if cur is new or not, add it to the new list,
+				 * if the new list has not started, cur will become the first item. */
+				if (prev) {
+					AST_LIST_NEXT(prev, frame_list) = cur;
+				} else {
+					f = cur; /* set f to be the beginning of our new list */
+				}
+				prev = cur;
 			}
 		}
 		




More information about the svn-commits mailing list