diff --git a/include/asterisk/file.h b/include/asterisk/file.h index 678f0d1f2f..a195b604ff 100644 --- a/include/asterisk/file.h +++ b/include/asterisk/file.h @@ -356,7 +356,7 @@ struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *filename, const char *preflang); /*! - * \brief Applies a open stream to a channel. + * \brief Applies a open stream to a channel. And bumps the reference count of the channel. * \param chan channel to work * \param s ast_filestream to apply * \retval 0 on success. diff --git a/main/file.c b/main/file.c index 039e33b19a..dfa9141500 100644 --- a/main/file.c +++ b/main/file.c @@ -449,6 +449,11 @@ static void filestream_destructor(void *arg) } } + /* Remove a reference to the owner channel if there is one from in ast_applystream */ + if (f->owner) { + f->owner = ast_channel_unref(f->owner); + } + ast_free(f->filename); ast_free(f->realfilename); if (f->vfs) @@ -1064,7 +1069,19 @@ static int ast_fsread_video(const void *data) int ast_applystream(struct ast_channel *chan, struct ast_filestream *s) { - s->owner = chan; + /* If no changes don't do anything */ + if (s->owner == chan) { + return 0; + } + + /* Remove reference to any existing channel */ + if (s->owner) { + ast_channel_unref(s->owner); + } + + /* Bump the ref count so the channel doesn't go away */ + s->owner = ast_channel_ref(chan); + return 0; }