diff --git a/main/audiohook.c b/main/audiohook.c index cddfd10356..d1dc6d0fde 100644 --- a/main/audiohook.c +++ b/main/audiohook.c @@ -582,8 +582,6 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st /* Here's the scoop... middle frame is no longer of use to us */ ast_frfree(middle_frame); } - /* Yay let's rid ourselves of the start frame */ - ast_frfree(start_frame); } else { /* No frame was modified, we can just drop our middle frame and pass the frame we got in out */ ast_frfree(middle_frame); diff --git a/main/channel.c b/main/channel.c index 8e1f59b0bd..83389a7210 100644 --- a/main/channel.c +++ b/main/channel.c @@ -2313,8 +2313,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION; ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name); } - if (chan->audiohooks) + if (chan->audiohooks) { + struct ast_frame *old_frame = f; f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); + if (old_frame != f) + ast_frfree(old_frame); + } } else { struct timeval now = ast_tvnow(); if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) { @@ -2336,8 +2340,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name); chan->dtmf_tv = now; } - if (chan->audiohooks) + if (chan->audiohooks) { + struct ast_frame *old_frame = f; f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); + if (old_frame != f) + ast_frfree(old_frame); + } } break; case AST_FRAME_DTMF_BEGIN: @@ -2399,8 +2407,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) f->subclass = chan->emulate_dtmf_digit; f->len = ast_tvdiff_ms(now, chan->dtmf_tv); chan->dtmf_tv = now; - if (chan->audiohooks) + if (chan->audiohooks) { + struct ast_frame *old_frame = f; f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); + if (old_frame != f) + ast_frfree(old_frame); + } ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name); } else { /* Drop voice frames while we're still in the middle of the digit */ @@ -2416,8 +2428,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) f = &ast_null_frame; } else if ((f->frametype == AST_FRAME_VOICE)) { /* Send frame to audiohooks if present */ - if (chan->audiohooks) + if (chan->audiohooks) { + struct ast_frame *old_frame = f; f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); + if (old_frame != f) + ast_frfree(old_frame); + } if (chan->monitor && chan->monitor->read_stream ) { /* XXX what does this do ? */ #ifndef MONITOR_CONSTANT_DELAY @@ -2707,7 +2723,7 @@ int ast_write_video(struct ast_channel *chan, struct ast_frame *fr) int ast_write(struct ast_channel *chan, struct ast_frame *fr) { int res = -1; - struct ast_frame *f = NULL; + struct ast_frame *f = NULL, *f2 = NULL; /* Stop if we're a zombie or need a soft hangup */ ast_channel_lock(chan); @@ -2755,8 +2771,12 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr) chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen); break; case AST_FRAME_DTMF_BEGIN: - if (chan->audiohooks) + if (chan->audiohooks) { + struct ast_frame *old_frame = fr; fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); + if (old_frame != fr) + f = fr; + } send_dtmf_event(chan, "Sent", fr->subclass, "Yes", "No"); ast_clear_flag(chan, AST_FLAG_BLOCKING); ast_channel_unlock(chan); @@ -2765,8 +2785,12 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr) CHECK_BLOCKING(chan); break; case AST_FRAME_DTMF_END: - if (chan->audiohooks) + if (chan->audiohooks) { + struct ast_frame *old_frame = fr; fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); + if (old_frame != fr) + f = fr; + } send_dtmf_event(chan, "Sent", fr->subclass, "No", "Yes"); ast_clear_flag(chan, AST_FLAG_BLOCKING); ast_channel_unlock(chan); @@ -2801,9 +2825,13 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr) break; /*! \todo XXX should return 0 maybe ? */ /* If audiohooks are present, write the frame out */ - if (chan->audiohooks) + if (chan->audiohooks) { + struct ast_frame *old_frame = fr; fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); - + if (old_frame != fr) + f2 = 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) f = fr; @@ -2858,6 +2886,8 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr) if (f && f != fr) ast_frfree(f); + if (f2) + ast_frfree(f2); ast_clear_flag(chan, AST_FLAG_BLOCKING); /* Consider a write failure to force a soft hangup */ if (res < 0)