diff --git a/res/res_fax.c b/res/res_fax.c index 16a3d58..230c607 100644 --- a/res/res_fax.c +++ b/res/res_fax.c @@ -278,12 +278,12 @@ struct fax_detect { int timeout; /*! \brief DSP Processor */ struct ast_dsp *dsp; - /*! \brief original audio formats */ - struct ast_format orig_format; /*! \brief fax session details */ struct ast_fax_session_details *details; /*! \brief mode */ int flags; + /*! \brief translator path for transcoding to slinear */ + struct ast_trans_pvt* trans; }; /*! \brief FAX Detect flags */ @@ -3275,6 +3275,8 @@ static struct fax_detect *fax_detect_new(struct ast_channel *chan, int timeout, faxdetect->dsp = NULL; } + faxdetect->trans = NULL; + return faxdetect; } @@ -3283,6 +3285,9 @@ static struct fax_detect *fax_detect_new(struct ast_channel *chan, int timeout, static void fax_detect_framehook_destroy(void *data) { struct fax_detect *faxdetect = data; + if (faxdetect->trans) + ast_translator_free_path(faxdetect->trans); + ao2_ref(faxdetect, -1); } @@ -3301,34 +3306,19 @@ static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct a struct fax_detect *faxdetect = data; struct ast_fax_session_details *details; struct ast_control_t38_parameters *control_params; - struct ast_channel *peer; + //struct ast_channel *peer; + struct ast_format slin; + struct ast_frame *o; int result = 0; + o = NULL; details = faxdetect->details; + ast_debug(5, "fax_detect_framehook called with event %d.\n", event); + switch (event) { case AST_FRAMEHOOK_EVENT_ATTACHED: - /* Setup format for DSP on ATTACH*/ - ast_format_copy(&faxdetect->orig_format, ast_channel_readformat(chan)); - switch (ast_channel_readformat(chan)->id) { - case AST_FORMAT_SLINEAR: - case AST_FORMAT_ALAW: - case AST_FORMAT_ULAW: - break; - default: - if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) { - ast_framehook_detach(chan, details->faxdetect_id); - details->faxdetect_id = -1; - return f; - } - } - return NULL; case AST_FRAMEHOOK_EVENT_DETACHED: - /* restore audio formats when we are detached */ - ast_set_read_format(chan, &faxdetect->orig_format); - if ((peer = ast_bridged_channel(chan))) { - ast_channel_make_compatible(chan, peer); - } return NULL; case AST_FRAMEHOOK_EVENT_READ: if (f) { @@ -3363,7 +3353,22 @@ static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct a case AST_FORMAT_ULAW: break; default: - return f; + if (!faxdetect->trans) { + ast_debug(5, "Attempt to process %s frame in CNG fax detection.\n", ast_getformatname(&f->subclass.format)); + ast_format_set(&slin, AST_FORMAT_SLINEAR, 0); + faxdetect->trans = ast_translator_build_path(&slin, &f->subclass.format); + } + if (!faxdetect->trans) { + ast_debug(5, "Unable to build translation path to slinear.\n"); + return f; + } + o = f; + f = ast_translate(faxdetect->trans, f, 0); + if (!f) { + ast_debug(5, "Transcoding failed.\n"); + return o; + } + break; } break; case AST_FRAME_CONTROL: @@ -3408,8 +3413,8 @@ static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct a if (ast_async_goto(chan, target_context, "fax", 1)) { ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(chan), target_context); } - ast_frfree(f); - f = &ast_null_frame; + ast_frfree(o); + o = &ast_null_frame; } else { ast_channel_lock(chan); ast_log(LOG_NOTICE, "FAX %s detected but no fax extension in context (%s)\n", @@ -3420,7 +3425,8 @@ static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct a details->faxdetect_id = -1; } - return f; + ast_frfree(f); + return o; } /*! \brief Attach a faxdetect framehook object to a channel.