diff --git a/include/asterisk/file.h b/include/asterisk/file.h
index e1dd99e268dd9d4e1f9778fbb13769abe0bc39e0..43b32fd12a7faf61712976bd5534435f3a2f7fe5 100644
--- a/include/asterisk/file.h
+++ b/include/asterisk/file.h
@@ -315,21 +315,6 @@ off_t ast_tellstream(struct ast_filestream *fs);
  */ 
 struct ast_frame *ast_readframe(struct ast_filestream *s);
 
-/*!\brief destroy a filestream using an ast_frame as input
- *
- * This is a hack that is used also by the ast_trans_pvt and
- * ast_dsp structures. When a structure contains an ast_frame
- * pointer as one of its fields. It may be that the frame is
- * still used after the outer structure is freed. This leads to
- * invalid memory accesses. This function allows for us to hold
- * off on destroying the ast_filestream until we are done using
- * the ast_frame pointer that is part of it
- *
- * \param fr The ast_frame that is part of an ast_filestream we wish
- * to free.
- */
-void ast_filestream_frame_freed(struct ast_frame *fr);
-
 /*! Initialize file stuff */
 /*!
  * Initializes all the various file stuff.  Basically just registers the cli stuff
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index db90e1845999b967c3f4c2d2dcf8370ff5b418b2..7246aad8334b377dc92dd3e1b90e078fcd848f45 100644
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -136,10 +136,6 @@ enum {
 	 *  The dsp cannot be free'd if the frame inside of it still has
 	 *  this flag set. */
 	AST_FRFLAG_FROM_DSP = (1 << 2),
-	/*! This frame came from a filestream and is still the original frame.
-	 *  The filestream cannot be free'd if the frame inside of it still has
-	 *  this flag set. */
-	AST_FRFLAG_FROM_FILESTREAM = (1 << 3),
 };
 
 /*! \brief Data structure associated with a single frame of data
diff --git a/main/file.c b/main/file.c
index 5855f45227eb3e0b62680beb3d39517306ee72f0..10764c67f7d9662cd3ca1ce33a1b24173eaabf6c 100644
--- a/main/file.c
+++ b/main/file.c
@@ -688,17 +688,36 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *fil
 	return NULL;
 }
 
-struct ast_frame *ast_readframe(struct ast_filestream *s)
+static struct ast_frame *read_frame(struct ast_filestream *s, int *whennext)
 {
-	struct ast_frame *f = NULL;
-	int whennext = 0;	
-	if (s && s->fmt)
-		f = s->fmt->read(s, &whennext);
-	if (f) {
-		ast_set_flag(f, AST_FRFLAG_FROM_FILESTREAM);
-		ao2_ref(s, +1);
+	struct ast_frame *fr, *new_fr;
+
+	if (!s || !s->fmt) {
+		return NULL;
+	}
+
+	if (!(fr = s->fmt->read(s, whennext))) {
+		return NULL;
+	}
+
+	if (!(new_fr = ast_frisolate(fr))) {
+		ast_frfree(fr);
+		return NULL;
+	}
+
+	if (new_fr != fr) {
+		ast_frfree(fr);
+		fr = new_fr;
 	}
-	return f;
+
+	return fr;
+}
+
+struct ast_frame *ast_readframe(struct ast_filestream *s)
+{
+	int whennext = 0;
+
+	return read_frame(s, &whennext);
 }
 
 enum fsread_res {
@@ -715,15 +734,13 @@ static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
 
 	while (!whennext) {
 		struct ast_frame *fr;
-		
-		if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name))
+
+		if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) {
 			goto return_failure;
-		
-		fr = s->fmt->read(s, &whennext);
-		if (fr) {
-			ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
-			ao2_ref(s, +1);
 		}
+
+		fr = read_frame(s, &whennext);
+
 		if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
 			if (fr) {
 				ast_log(LOG_WARNING, "Failed to write frame\n");
@@ -731,10 +748,12 @@ static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
 			}
 			goto return_failure;
 		} 
+
 		if (fr) {
 			ast_frfree(fr);
 		}
 	}
+
 	if (whennext != s->lasttimeout) {
 		if (s->owner->timingfd > -1) {
 			float samp_rate = (float) ast_format_rate(s->fmt->format);
@@ -778,11 +797,8 @@ static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
 	int whennext = 0;
 
 	while (!whennext) {
-		struct ast_frame *fr = s->fmt->read(s, &whennext);
-		if (fr) {
-			ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
-			ao2_ref(s, +1);
-		}
+		struct ast_frame *fr = read_frame(s, &whennext);
+
 		if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
 			if (fr) {
 				ast_log(LOG_WARNING, "Failed to write frame\n");
@@ -791,6 +807,7 @@ static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
 			s->owner->vstreamid = -1;
 			return FSREAD_FAILURE;
 		}
+
 		if (fr) {
 			ast_frfree(fr);
 		}
@@ -882,20 +899,6 @@ int ast_closestream(struct ast_filestream *f)
 		}
 	}
 
-	if (ast_test_flag(&f->fr, AST_FRFLAG_FROM_FILESTREAM)) {
-		/* If this flag is still set, it essentially means that the reference
-		 * count of f is non-zero. We can't destroy this filestream until
-		 * whatever is using the filestream's frame has finished.
-		 *
-		 * Since this was called, however, we need to remove the reference from
-		 * when this filestream was first allocated. That way, when the embedded
-		 * frame is freed, the refcount will reach 0 and we can finish destroying
-		 * this filestream properly.
-		 */
-		ao2_ref(f, -1);
-		return 0;
-	}
-	
 	ao2_ref(f, -1);
 	return 0;
 }
@@ -1327,17 +1330,6 @@ int ast_waitstream_exten(struct ast_channel *c, const char *context)
 		-1, -1, context);
 }
 
-void ast_filestream_frame_freed(struct ast_frame *fr)
-{
-	struct ast_filestream *fs;
-
-	ast_clear_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
-
-	fs = (struct ast_filestream *) (((char *) fr) - offsetof(struct ast_filestream, fr));
-
-	ao2_ref(fs, -1);
-}
-
 /*
  * if the file name is non-empty, try to play it.
  * Return 0 if success, -1 if error, digit if interrupted by a digit.
diff --git a/main/frame.c b/main/frame.c
index 7b8a3cc9fbef444a8880a50be5f0c7327ce97aea..1b8dead2a3f668a1a910a5b8d997f58101c746f4 100644
--- a/main/frame.c
+++ b/main/frame.c
@@ -336,8 +336,6 @@ static void __frame_free(struct ast_frame *fr, int cache)
 		ast_translate_frame_freed(fr);
 	} else if (ast_test_flag(fr, AST_FRFLAG_FROM_DSP)) {
 		ast_dsp_frame_freed(fr);
-	} else if (ast_test_flag(fr, AST_FRFLAG_FROM_FILESTREAM)) {
-		ast_filestream_frame_freed(fr);
 	}
 
 	if (!fr->mallocd)
@@ -426,7 +424,6 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr)
 	} else {
 		ast_clear_flag(fr, AST_FRFLAG_FROM_TRANSLATOR);
 		ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
-		ast_clear_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
 		out = fr;
 	}