memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = AST_FRAME_NULL;
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
dsp->f.frametype = AST_FRAME_CONTROL;
dsp->f.subclass = AST_CONTROL_BUSY;
ast_frfree(af);
- ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
} else {
ast_queue_frame(chan, af);
ast_frfree(af);
}
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
} else {
memset(&dsp->f, 0, sizeof(dsp->f));
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
}
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
} else {
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
}
void ast_dsp_free(struct ast_dsp *dsp)
{
+ if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) {
+ /* If this flag is still set, that means that the dsp's destruction
+ * been torn down, while we still have a frame out there being used.
+ * When ast_frfree() gets called on that frame, this ast_trans_pvt
+ * will get destroyed, too. */
+
+ /* Set the magic hint that this has been requested to be destroyed. */
+ dsp->freqcount = -1;
+
+ return;
+ }
free(dsp);
}
{
return dsp->tcount;
}
+
+void ast_dsp_frame_freed(struct ast_frame *fr)
+{
+ struct ast_dsp *dsp;
+
+ ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
+
+ dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f));
+
+ if (dsp->freqcount != -1)
+ return;
+
+ ast_dsp_free(dsp);
+}
{
if (ast_test_flag(fr, AST_FRFLAG_FROM_TRANSLATOR))
ast_translate_frame_freed(fr);
+ else if (ast_test_flag(fr, AST_FRFLAG_FROM_DSP))
+ ast_dsp_frame_freed(fr);
if (!fr->mallocd)
return;
void *newdata;
ast_clear_flag(fr, AST_FRFLAG_FROM_TRANSLATOR);
+ ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
if (!(fr->mallocd & AST_MALLOCD_HDR)) {
/* Allocate a new header if needed */