@ -3914,6 +3914,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
struct ast_frame * readq_tail = AST_LIST_LAST ( ast_channel_readq ( chan ) ) ;
struct ast_control_read_action_payload * read_action_payload ;
struct ast_party_connected_line connected ;
int hooked = 0 ;
/* if the channel driver returned more than one frame, stuff the excess
into the readq for the next ast_read call
@ -4191,15 +4192,22 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
break ;
}
}
/* Send frame to audiohooks if present */
if ( ast_channel_audiohooks ( chan ) ) {
/*
* Send frame to audiohooks if present , if frametype is linear , to preserve
* functional compatibility with previous behavior . If not linear , hold off
* until transcoding is done where we are more likely to have a linear frame
*/
if ( ast_channel_audiohooks ( chan ) & & ast_format_cache_is_slinear ( f - > subclass . format ) ) {
/* Place hooked after declaration */
struct ast_frame * old_frame = f ;
hooked = 1 ;
f = ast_audiohook_write_list ( chan , ast_channel_audiohooks ( chan ) , AST_AUDIOHOOK_DIRECTION_READ , f ) ;
if ( old_frame ! = f ) {
ast_frfree ( old_frame ) ;
}
}
if ( ast_channel_monitor ( chan ) & & ast_channel_monitor ( chan ) - > read_stream ) {
/* XXX what does this do ? */
# ifndef MONITOR_CONSTANT_DELAY
@ -4242,6 +4250,16 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
}
}
/* Second chance at hooking a linear frame, also the last chance */
if ( ast_channel_audiohooks ( chan ) & & ! hooked ) {
struct ast_frame * old_frame = f ;
f = ast_audiohook_write_list ( chan , ast_channel_audiohooks ( chan ) , AST_AUDIOHOOK_DIRECTION_READ , f ) ;
if ( old_frame ! = f ) {
ast_frfree ( old_frame ) ;
}
}
/*
* It is possible for the translation process on the channel to have
* produced multiple frames from the single input frame we passed it ; if
@ -5032,6 +5050,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
int res = - 1 ;
struct ast_frame * f = NULL ;
int count = 0 ;
int hooked = 0 ;
/*Deadlock avoidance*/
while ( ast_channel_trylock ( chan ) ) {
@ -5149,6 +5168,22 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
apply_plc ( chan , fr ) ;
}
/*
* Send frame to audiohooks if present , if frametype is linear ( else , later as per
* previous behavior )
*/
if ( ast_channel_audiohooks ( chan ) ) {
if ( ast_format_cache_is_slinear ( fr - > subclass . format ) ) {
struct ast_frame * old_frame ;
hooked = 1 ;
old_frame = fr ;
fr = ast_audiohook_write_list ( chan , ast_channel_audiohooks ( chan ) , AST_AUDIOHOOK_DIRECTION_WRITE , fr ) ;
if ( old_frame ! = fr ) {
ast_frfree ( old_frame ) ;
}
}
}
/* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
if ( ast_format_cmp ( fr - > subclass . format , ast_channel_rawwriteformat ( chan ) ) = = AST_FORMAT_CMP_EQUAL ) {
f = fr ;
@ -5186,7 +5221,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
break ;
}
if ( ast_channel_audiohooks ( chan ) ) {
if ( ast_channel_audiohooks ( chan ) & & ! hooked ) {
struct ast_frame * prev = NULL , * new_frame , * cur , * dup ;
int freeoldlist = 0 ;