diff --git a/README.codecnegotiation-branch b/README.codecnegotiation-branch new file mode 100644 index 0000000..5e9146a --- /dev/null +++ b/README.codecnegotiation-branch @@ -0,0 +1,66 @@ +Codec API changes branch +======================== + +Why do we need this? +--------------------- + +There are many problems with the existing codec negotiation implementation, many +people wants to change it. But all has one unresolved problem -- all changes, +related to codec negotiation, need to modify all channel modules and most +applications. + +This problem exists, because there is no easy and consistend API, that can be +used for some standard situations, and there are a lot of duplicated code. + +What is the main idea of this patches? +--------------------------------------- + +I think, that direct access to chan->(raw)(read|write|native)format can be only +from special functions. Loadable modules don't need to has direct access to +this variables, only through channel API. + +After incorporating this to trunk, we could easily incorporate all patches like +4825 (codec negotiation rework). + +This patch DO NOT CHANGE any existing API's, only add some new functions, and +convert most of code to using new API. + +Changes description +------------------- + +Added functions (all this functions static inline): + + - ast_channel_best_codec(chan) = ast_best_codec(chan->nativecodecs) + This need, because in future nativecodecs can be changed from int to struct + type; + - ast_get_read_format(chan) = chan->readformat + - ast_get_write_format(chan) = chan->writeformat + - ast_request_inherit -- wrapper around ast_request, that can: + - copy type from parent channel, if type not set; + - copy formats from parent channel; + - ast_channel_getformatname = ast_getformatname(chan->nativeformats) + - ast_channel_format_reset = + ast_set_read_format(chan->readformat); + ast_set_write_format(chan->writeformat); + +Related changes: + - most places, where can be used new functions changed to use it + +Progress +-------- + - ast_chan_best_codec(chan) -- all modules fixed + - ast_get_(read|write)_format -- ~80% modules fixed (may be fixed after commit + as junitor project) + - ast_request_inherit -- all modules fixed (would be used for easily + integrate 4825 -- it contain many chunks with ast_request); + +Contacts +-------- + +If you have questions about this patches, or ideas for improvement, write me: +Denis Smirnov + +Discussions are best done on the asterisk-dev mailing list. + +Bugs are reported to the bug tracker, issue #6725 + diff --git a/apps/app_amd.c b/apps/app_amd.c index e5dee1e..9739e61 100644 --- a/apps/app_amd.c +++ b/apps/app_amd.c @@ -129,7 +129,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data) ); if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "AMD: %s %s %s (Fmt: %d)\n", chan->name ,chan->cid.cid_ani, chan->cid.cid_rdnis, chan->readformat); + ast_verbose(VERBOSE_PREFIX_3 "AMD: %s %s %s (Fmt: %d)\n", chan->name ,chan->cid.cid_ani, chan->cid.cid_rdnis, ast_get_read_format(chan)); /* Lets parse the arguments. */ if (!ast_strlen_zero(parse)) { @@ -162,7 +162,7 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data) minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold ); /* Set read format to signed linear so we get signed linear frames in */ - readFormat = chan->readformat; + readFormat = ast_get_read_format(chan); if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0 ) { ast_log(LOG_WARNING, "AMD: Channel [%s]. Unable to set to linear mode, giving up\n", chan->name ); pbx_builtin_setvar_helper(chan , "AMDSTATUS", ""); diff --git a/apps/app_chanisavail.c b/apps/app_chanisavail.c index c6931d8..5c2c8d1 100644 --- a/apps/app_chanisavail.c +++ b/apps/app_chanisavail.c @@ -121,7 +121,7 @@ static int chanavail_exec(struct ast_channel *chan, void *data) snprintf(trychan, sizeof(trychan), "%s/%s",cur,number); status = inuse = ast_device_state(trychan); } - if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) { + if ((inuse <= 1) && (tempchan = ast_request_inherit(chan, tech, number, &status))) { pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name); /* Store the originally used channel too */ snprintf(tmp, sizeof(tmp), "%s/%s", tech, number); diff --git a/apps/app_dial.c b/apps/app_dial.c index 7f731bc..347a384 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1288,7 +1288,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags } ast_copy_string(numsubst, number, sizeof(numsubst)); /* Request the peer */ - tc = ast_request(tech, chan->nativeformats, numsubst, &cause); + tc = ast_request_inherit(chan, tech, numsubst, &cause); if (!tc) { /* If we can't, just go on to the next call */ ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", @@ -1328,7 +1328,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", chan->name, tech, stuff); } else { - tc = ast_request(tech, chan->nativeformats, stuff, &cause); + tc= ast_request_inherit(chan, tech, stuff, &cause); } if (!tc) ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); diff --git a/apps/app_dictate.c b/apps/app_dictate.c index 55d8ba9..03232ce 100644 --- a/apps/app_dictate.c +++ b/apps/app_dictate.c @@ -119,7 +119,7 @@ static int dictate_exec(struct ast_channel *chan, void *data) if (args.argc > 1 && args.filename) { filename = args.filename; } - oldr = chan->readformat; + oldr = ast_get_read_format(chan); if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) { ast_log(LOG_WARNING, "Unable to set to linear mode.\n"); ast_module_user_remove(u); diff --git a/apps/app_dumpchan.c b/apps/app_dumpchan.c index ca7897e..7676d28 100644 --- a/apps/app_dumpchan.c +++ b/apps/app_dumpchan.c @@ -115,8 +115,8 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size) c->_state, c->rings, ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->nativeformats), - ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->writeformat), - ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->readformat), + ast_getformatname_multiple(formatbuf, sizeof(formatbuf), ast_get_write_format(c)), + ast_getformatname_multiple(formatbuf, sizeof(formatbuf), ast_get_read_format(c)), c->fds[0], c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup, hour, diff --git a/apps/app_echo.c b/apps/app_echo.c index 4b2c940..bcd431e 100644 --- a/apps/app_echo.c +++ b/apps/app_echo.c @@ -54,14 +54,11 @@ static char *descrip = static int echo_exec(struct ast_channel *chan, void *data) { int res = -1; - int format; struct ast_module_user *u; u = ast_module_user_add(chan); - - format = ast_best_codec(chan->nativeformats); - ast_set_write_format(chan, format); - ast_set_read_format(chan, format); + + ast_set_best_format(chan); while (ast_waitfor(chan, -1) > -1) { struct ast_frame *f = ast_read(chan); diff --git a/apps/app_festival.c b/apps/app_festival.c index 1fa935e..1a4b179 100644 --- a/apps/app_festival.c +++ b/apps/app_festival.c @@ -191,7 +191,7 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in ast_stopstream(chan); ast_indicate(chan, -1); - owriteformat = chan->writeformat; + owriteformat = ast_get_write_format(chan); res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); diff --git a/apps/app_ices.c b/apps/app_ices.c index 91725fd..b6b40fe 100644 --- a/apps/app_ices.c +++ b/apps/app_ices.c @@ -143,7 +143,7 @@ static int ices_exec(struct ast_channel *chan, void *data) return -1; } - oreadformat = chan->readformat; + oreadformat = ast_get_read_format(chan); res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { close(fds[0]); diff --git a/apps/app_mp3.c b/apps/app_mp3.c index e0df37d..1bd479b 100644 --- a/apps/app_mp3.c +++ b/apps/app_mp3.c @@ -154,7 +154,7 @@ static int mp3_exec(struct ast_channel *chan, void *data) ast_stopstream(chan); - owriteformat = chan->writeformat; + owriteformat = ast_get_write_format(chan); res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); diff --git a/apps/app_nbscat.c b/apps/app_nbscat.c index 1fb51e6..c6bfa66 100644 --- a/apps/app_nbscat.c +++ b/apps/app_nbscat.c @@ -139,7 +139,7 @@ static int NBScat_exec(struct ast_channel *chan, void *data) ast_stopstream(chan); - owriteformat = chan->writeformat; + owriteformat = ast_get_write_format(chan); res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); diff --git a/apps/app_queue.c b/apps/app_queue.c index 716141c..ab8bf5b 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1652,7 +1652,7 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies location = ""; /* Request the peer */ - tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status); + tmp->chan = ast_request_inherit(qe->chan, tech, location, &status); if (!tmp->chan) { /* If we can't, just go on to the next call */ if (qe->chan->cdr) ast_cdr_busy(qe->chan->cdr); @@ -1979,7 +1979,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name); /* Setup parameters */ - o->chan = ast_request(tech, in->nativeformats, stuff, &status); + o->chan = ast_request_inherit(in, tech, stuff, &status); if (status != o->oldstatus) update_dial_status(qe->parent, o->member, status); if (!o->chan) { diff --git a/apps/app_record.c b/apps/app_record.c index e06d84a..b58b74e 100644 --- a/apps/app_record.c +++ b/apps/app_record.c @@ -247,7 +247,7 @@ static int record_exec(struct ast_channel *chan, void *data) /* The end of beep code. Now the recording starts */ if (silence > 0) { - rfmt = chan->readformat; + rfmt = ast_get_read_format(chan); res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); diff --git a/apps/app_talkdetect.c b/apps/app_talkdetect.c index 7d9376a..78f0b88 100644 --- a/apps/app_talkdetect.c +++ b/apps/app_talkdetect.c @@ -111,7 +111,7 @@ static int background_detect_exec(struct ast_channel *chan, void *data) res = ast_answer(chan); } if (!res) { - origrformat = chan->readformat; + origrformat = ast_get_read_format(chan); if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR))) ast_log(LOG_WARNING, "Unable to set read format to linear!\n"); } diff --git a/apps/app_test.c b/apps/app_test.c index 02c354f..fda5019 100644 --- a/apps/app_test.c +++ b/apps/app_test.c @@ -72,7 +72,7 @@ static int measurenoise(struct ast_channel *chan, int ms, char *who) struct timeval start; struct ast_frame *f; int rformat; - rformat = chan->readformat; + rformat = ast_get_read_format(chan); if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { ast_log(LOG_NOTICE, "Unable to set to linear mode!\n"); return -1; diff --git a/apps/app_waitforsilence.c b/apps/app_waitforsilence.c index 55fc714..2c7f271 100644 --- a/apps/app_waitforsilence.c +++ b/apps/app_waitforsilence.c @@ -84,7 +84,7 @@ static int do_waiting(struct ast_channel *chan, int silencereqd, time_t waitstar struct ast_dsp *sildet; /* silence detector dsp */ time_t now; - rfmt = chan->readformat; /* Set to linear mode */ + rfmt = ast_get_read_format(chan); /* Set to linear mode */ res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { ast_log(LOG_WARNING, "Unable to set channel to linear mode, giving up\n"); diff --git a/channels/chan_agent.c b/channels/chan_agent.c index c83df41..bddc84d 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -200,12 +200,11 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt); /*!< Holds the list of agents (l ast->nativeformats = p->chan->nativeformats; \ if (option_debug) \ ast_log(LOG_DEBUG, "Resetting read to %d and write to %d\n", ast->readformat, ast->writeformat);\ - ast_set_read_format(ast, ast->readformat); \ - ast_set_write_format(ast, ast->writeformat); \ + ast_channel_formats_reset(ast); \ } \ - if (p->chan->readformat != ast->rawreadformat) \ + if (ast_get_read_format(p->chan) != ast->rawreadformat) \ ast_set_read_format(p->chan, ast->rawreadformat); \ - if (p->chan->writeformat != ast->rawwriteformat) \ + if (ast_get_write_format(p->chan) != ast->rawwriteformat) \ ast_set_write_format(p->chan, ast->rawwriteformat); \ } \ } while(0) @@ -666,22 +665,22 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout) ast_log(LOG_DEBUG, "Waited for stream, result '%d'\n", res); } if (!res) { - res = ast_set_read_format(p->chan, ast_best_codec(p->chan->nativeformats)); + res = ast_set_read_format(p->chan, ast_channel_best_codec(p->chan)); if (option_debug > 2) ast_log(LOG_DEBUG, "Set read format, result '%d'\n", res); if (res) - ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats))); + ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(ast_channel_best_codec(p->chan))); } else { /* Agent hung-up */ p->chan = NULL; } if (!res) { - res = ast_set_write_format(p->chan, ast_best_codec(p->chan->nativeformats)); + res = ast_set_write_format(p->chan, ast_channel_best_codec(p->chan)); if (option_debug > 2) ast_log(LOG_DEBUG, "Set write format, result '%d'\n", res); if (res) - ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats))); + ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(ast_channel_best_codec(p->chan))); } if(!res) { /* Call is immediately up, or might need ack */ @@ -1970,14 +1969,14 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode) AST_LIST_LOCK(&agents); ast_mutex_lock(&p->lock); if (!res) { - res = ast_set_read_format(chan, ast_best_codec(chan->nativeformats)); + res = ast_set_read_format(chan, ast_channel_best_codec(chan)); if (res) - ast_log(LOG_WARNING, "Unable to set read format to %d\n", ast_best_codec(chan->nativeformats)); + ast_log(LOG_WARNING, "Unable to set read format to %d\n", ast_channel_best_codec(chan)); } if (!res) { - res = ast_set_write_format(chan, ast_best_codec(chan->nativeformats)); + res = ast_set_write_format(chan, ast_channel_best_codec(chan)); if (res) - ast_log(LOG_WARNING, "Unable to set write format to %d\n", ast_best_codec(chan->nativeformats)); + ast_log(LOG_WARNING, "Unable to set write format to %d\n", ast_channel_best_codec(chan)); } /* Check once more just in case */ if (p->chan) @@ -2026,7 +2025,7 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode) ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGIN", "%s", chan->name); if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "Agent '%s' logged in (format %s/%s)\n", p->agent, - ast_getformatname(chan->readformat), ast_getformatname(chan->writeformat)); + ast_getformatname(ast_get_read_format(chan)), ast_getformatname(chan->writeformat)); /* Login this channel and wait for it to go away */ p->chan = chan; if (p->ackcall > 1) diff --git a/channels/chan_features.c b/channels/chan_features.c index 3c1285c..e8c9be9 100644 --- a/channels/chan_features.c +++ b/channels/chan_features.c @@ -187,12 +187,9 @@ static void update_features(struct feature_pvt *p, int index) p->subs[index].owner->timingfd = p->subchan->timingfd; p->subs[index].owner->alertpipe[0] = p->subchan->alertpipe[0]; p->subs[index].owner->alertpipe[1] = p->subchan->alertpipe[1]; - if (p->subs[index].owner->nativeformats != p->subchan->readformat) { - p->subs[index].owner->nativeformats = p->subchan->readformat; - if (p->subs[index].owner->readformat) - ast_set_read_format(p->subs[index].owner, p->subs[index].owner->readformat); - if (p->subs[index].owner->writeformat) - ast_set_write_format(p->subs[index].owner, p->subs[index].owner->writeformat); + if (p->subs[index].owner->nativeformats != ast_get_read_format(p->subchan)) { + p->subs[index].owner->nativeformats = ast_get_read_format(p->subchan); + ast_channel_formats_reset(p->subs[index].owner); } } else{ restore_channel(p, index); @@ -481,11 +478,11 @@ static struct ast_channel *features_new(struct feature_pvt *p, int state, int in return NULL; } tmp->tech = &features_tech; - tmp->writeformat = p->subchan->writeformat; + tmp->writeformat = ast_get_write_format(p->subchan); tmp->rawwriteformat = p->subchan->rawwriteformat; - tmp->readformat = p->subchan->readformat; + tmp->readformat = ast_get_read_format(p->subchan); tmp->rawreadformat = p->subchan->rawreadformat; - tmp->nativeformats = p->subchan->readformat; + tmp->nativeformats = ast_get_read_format(p->subchan); tmp->tech_pvt = p; p->subs[index].owner = tmp; if (!p->owner) diff --git a/channels/chan_h323.c b/channels/chan_h323.c index 096e8dd..008864b 100644 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -342,8 +342,7 @@ static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt) if (h323debug) ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name); c->nativeformats = pvt->nativeformats; - ast_set_read_format(c, c->readformat); - ast_set_write_format(c, c->writeformat); + ast_channel_formats_reset(c); } if (pvt->needhangup) { if (h323debug) @@ -784,8 +783,7 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt) ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); pvt->owner->nativeformats = f->subclass; pvt->nativeformats = f->subclass; - ast_set_read_format(pvt->owner, pvt->owner->readformat); - ast_set_write_format(pvt->owner, pvt->owner->writeformat); + ast_channel_formats_reset(pvt->owner); ast_channel_unlock(pvt->owner); } /* Do in-band DTMF detection */ @@ -850,7 +848,7 @@ static int oh323_write(struct ast_channel *c, struct ast_frame *frame) } else { if (!(frame->subclass & c->nativeformats)) { ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", - frame->subclass, c->nativeformats, c->readformat, c->writeformat); + frame->subclass, c->nativeformats, ast_get_read_format(c), ast_get_write_format(c)); return 0; } } @@ -1031,7 +1029,7 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c fmt = global_options.capability; ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/; pvt->nativeformats = ch->nativeformats; - fmt = ast_best_codec(ch->nativeformats); + fmt = ast_channel_best_codec(ch); ch->writeformat = fmt; ch->rawwriteformat = fmt; ch->readformat = fmt; diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index a1cba30..4ce727e 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -6188,8 +6188,8 @@ static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2) chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "IAXPeer/%s",chan2->name); if (chan2m && chan1m) { /* Make formats okay */ - chan1m->readformat = chan1->readformat; - chan1m->writeformat = chan1->writeformat; + chan1m->readformat = ast_get_read_format(chan1); + chan1m->writeformat = ast_get_write_format(chan1); ast_channel_masquerade(chan1m, chan1); /* Setup the extensions and such */ ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); @@ -6199,8 +6199,8 @@ static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2) /* We make a clone of the peer channel too, so we can play back the announcement */ /* Make formats okay */ - chan2m->readformat = chan2->readformat; - chan2m->writeformat = chan2->writeformat; + chan2m->readformat = ast_get_read_format(chan2); + chan2m->writeformat = ast_get_write_format(chan2); ast_channel_masquerade(chan2m, chan2); /* Setup the extensions and such */ ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); @@ -8100,8 +8100,7 @@ static struct ast_channel *iax2_request(const char *type, int format, void *data } c->nativeformats = native; } - c->readformat = ast_best_codec(c->nativeformats); - c->writeformat = c->readformat; + c->writeformat = c->readformat = ast_channel_best_codec(c); } return c; diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index bdb7047..df791c0 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -1204,8 +1204,7 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub) if (option_debug) ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); sub->owner->nativeformats = f->subclass; - ast_set_read_format(sub->owner, sub->owner->readformat); - ast_set_write_format(sub->owner, sub->owner->writeformat); + ast_channel_formats_reset(sub->owner); } /* Courtesy fearnor aka alex@pilosoft.com */ if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) { @@ -1244,7 +1243,7 @@ static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame) } else { if (!(frame->subclass & ast->nativeformats)) { ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", - frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); + frame->subclass, ast->nativeformats, ast_get_read_format(ast), ast_get_write_format(ast)); return -1; } } @@ -1439,7 +1438,7 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state) tmp->nativeformats = i->capability; if (!tmp->nativeformats) tmp->nativeformats = capability; - fmt = ast_best_codec(tmp->nativeformats); + fmt = ast_channel_best_codec(tmp); ast_string_field_build(tmp, name, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id); if (sub->rtp) tmp->fds[0] = ast_rtp_fd(sub->rtp); diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2707f0c..f6e98e7 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -3879,7 +3879,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit } /* XXX Why are we choosing a codec from the native formats?? */ - fmt = ast_best_codec(tmp->nativeformats); + fmt = ast_channel_best_codec(tmp); /* If we have a prefcodec setting, we have an inbound channel that set a preferred format for this call. Otherwise, we check the jointcapability @@ -4150,8 +4150,7 @@ static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p if (option_debug) ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; - ast_set_read_format(p->owner, p->owner->readformat); - ast_set_write_format(p->owner, p->owner->writeformat); + ast_channel_formats_reset(p->owner); } if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { f = ast_dsp_process(p->owner, p->vad, f); @@ -5257,8 +5256,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats)); } p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); - ast_set_read_format(p->owner, p->owner->readformat); - ast_set_write_format(p->owner, p->owner->writeformat); + ast_channel_formats_reset(p->owner); } /* Turn on/off music on hold if we are holding/unholding */ @@ -12738,8 +12736,8 @@ static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct } /* Make formats okay */ - transferee->readformat = chan1->readformat; - transferee->writeformat = chan1->writeformat; + transferee->readformat = ast_get_read_format(chan1); + transferee->writeformat = ast_get_write_format(chan1); /* Prepare for taking over the channel */ ast_channel_masquerade(transferee, chan1); @@ -12753,8 +12751,8 @@ static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct back the announcement */ /* Make formats okay */ - transferer->readformat = chan2->readformat; - transferer->writeformat = chan2->writeformat; + transferer->readformat = ast_get_read_format(chan2); + transferer->writeformat = ast_get_write_format(chan2); /* Prepare for taking over the channel */ ast_channel_masquerade(transferer, chan2); diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 927172e..66c3693 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -2502,8 +2502,7 @@ static struct ast_frame *skinny_rtp_read(struct skinny_subchannel *sub) if (option_debug) ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); ast->nativeformats = f->subclass; - ast_set_read_format(ast, ast->readformat); - ast_set_write_format(ast, ast->writeformat); + ast_channel_formats_reset(sub->owner); } } } @@ -2534,7 +2533,7 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame) } else { if (!(frame->subclass & ast->nativeformats)) { ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", - frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); + frame->subclass, ast->nativeformats, ast_get_read_format(ast), ast_get_write_format(ast)); return -1; } } @@ -2732,8 +2731,13 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state) tmp->tech_pvt = sub; tmp->nativeformats = l->capability; if (!tmp->nativeformats) +<<<<<<< .merge_file_rO1Utp tmp->nativeformats = default_capability; fmt = ast_best_codec(tmp->nativeformats); +======= + tmp->nativeformats = capability; + fmt = ast_channel_best_codec(tmp); +>>>>>>> .merge_file_9lWybm if (skinnydebug) ast_verbose("skinny_new: tmp->nativeformats=%d fmt=%d\n", tmp->nativeformats, fmt); if (sub->rtp) { diff --git a/funcs/func_channel.c b/funcs/func_channel.c index 77777a5..fe39893 100644 --- a/funcs/func_channel.c +++ b/funcs/func_channel.c @@ -73,9 +73,9 @@ static int func_channel_read(struct ast_channel *chan, const char *function, /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_VIDEO_MASK); */ ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_VIDEO_MASK), len); else if (!strcasecmp(data, "audioreadformat")) - ast_copy_string(buf, ast_getformatname(chan->readformat), len); + ast_copy_string(buf, ast_getformatname(ast_get_read_format(chan)), len); else if (!strcasecmp(data, "audiowriteformat")) - ast_copy_string(buf, ast_getformatname(chan->writeformat), len); + ast_copy_string(buf, ast_getformatname(ast_get_write_format(chan)), len); else if (!strcasecmp(data, "tonezone") && chan->zone) locked_copy_string(chan, buf, chan->zone->country, len); else if (!strcasecmp(data, "language")) diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 0d07b5d..3c7da70 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -152,7 +152,7 @@ extern "C" { #include "asterisk/utils.h" #include "asterisk/linkedlists.h" #include "asterisk/stringfields.h" -#include "asterisk/compiler.h" +#include "asterisk/options.h" #define AST_MAX_FDS 8 @@ -674,6 +674,18 @@ void ast_channel_free(struct ast_channel *); */ struct ast_channel *ast_request(const char *type, int format, void *data, int *status); + +/*! \brief call ast_request with format/type of parent channel + */ +static inline struct ast_channel *ast_request_inherit(struct ast_channel *chan, const char *type, void *data, int *status) +{ + if( type == NULL ) { + return ast_request(chan->tech->type, chan->nativeformats, data, status); + } else { + return ast_request(type, chan->nativeformats, data, status); + } +} + /*! * \brief Request a channel of a given type, with data as optional information used * by the low level module and attempt to place a call on it @@ -894,6 +906,28 @@ int ast_prod(struct ast_channel *chan); */ int ast_set_read_format(struct ast_channel *chan, int format); +/*! \brief Gets read format from channel chan + * \param chan channel to get info + * Get read format for channel + * Returns read format + */ +static inline int ast_get_read_format(struct ast_channel *chan) +{ + return chan->readformat; +} + +/*! Gets write format from channel chan */ +/*! + * \param chan channel to get info + * Get write format for channel + * Returns write format + */ +static inline int ast_get_write_format(struct ast_channel *chan) +{ + return chan->writeformat; +} + + /*! \brief Sets write format on channel chan * Set write format for channel to whichever component of "format" is best. * \param chan channel to change @@ -1105,6 +1139,67 @@ int ast_channel_setoption(struct ast_channel *channel, int option, void *data, i /* Choose the best codec... Uhhh... Yah. */ int ast_best_codec(int fmts); +/*! + * \brief Pick the best codec from channel nativeformats + * \param channel channel, from that nativeformats used + */ +static inline int ast_channel_best_codec(struct ast_channel *channel) +{ +#ifndef BUG_4825 + return ast_best_codec(channel->nativeformats); +#else + return ast_best_codec(channel->nativeformats.audio_bits); +#endif +} +/*! \brief Get the names of a set of formats + * \param buf a buffer for the output string + * \param size size of buf (bytes) + * \param channel the channel + * Prints a list of readable codec names corresponding to "format". + * ex: for format=AST_FORMAT_GSM|AST_FORMAT_SPEEX|AST_FORMAT_ILBC it will return "0x602 (GSM|SPEEX|ILBC)" + * \return The return value is buf. + */ +inline static char * ast_channel_getformatname_multiple(char *buf, size_t size, struct ast_channel *chan) +{ + return ast_getformatname_multiple(buf, size, chan->nativeformats); +} + + +static inline char * ast_channel_getformatname(struct ast_channel *chan) +{ +#ifndef BUG_4825 + return chan ? ast_getformatname(chan->nativeformats) : "undefined"; +#else + return chan ? ast_getformatname(chan->nativeformats.audio_bits) : "undefined"; +#endif +} + +static inline void ast_channel_formats_reset(struct ast_channel *channel) +{ + int r, w; + r = ast_get_read_format(channel); + w = ast_get_write_format(channel); + + if (option_debug) + ast_log(LOG_DEBUG, "Resetting read to %d and write to %d on channel %s\n", r, w, channel->name); + + if (r) + ast_set_read_format(channel, r); + + if (w) + ast_set_write_format(channel, w); +} + +/*! + * \brief Set best format, identical to read/write + * \param channel channel, from that nativeformats used and formats set + */ +static inline void ast_set_best_format(struct ast_channel *channel) +{ + int format = ast_channel_best_codec(channel); + ast_set_read_format(channel, format); + ast_set_write_format(channel, format); +} /*! Checks the value of an option */ /*! @@ -1418,3 +1513,4 @@ void ast_channel_whisper_stop(struct ast_channel *chan); #endif #endif /* _ASTERISK_CHANNEL_H */ + diff --git a/res/res_adsi.c b/res/res_adsi.c index 62f8381..34ee4f3 100644 --- a/res/res_adsi.c +++ b/res/res_adsi.c @@ -377,8 +377,8 @@ int ast_adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int writeformat, readformat; int waitforswitch = 0; - writeformat = chan->writeformat; - readformat = chan->readformat; + writeformat = ast_get_write_format(chan); + readformat = ast_get_read_format(chan); newdatamode = chan->adsicpe & ADSI_FLAG_DATAMODE; diff --git a/res/res_agi.c b/res/res_agi.c index 55f5c65..317738c 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -933,7 +933,7 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char } if (silence > 0) { - rfmt = chan->readformat; + rfmt = ast_get_read_format(chan); res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); @@ -2077,7 +2077,7 @@ static int eagi_exec(struct ast_channel *chan, void *data) if (chan->_softhangup) ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); - readformat = chan->readformat; + readformat = ast_get_read_format(chan); if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); return -1; diff --git a/res/res_features.c b/res/res_features.c index 1aba2c1..0ffacf0 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -447,8 +447,8 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int } /* Make formats okay */ - chan->readformat = rchan->readformat; - chan->writeformat = rchan->writeformat; + chan->readformat = ast_get_read_format(rchan); + chan->writeformat = ast_get_write_format(rchan); ast_channel_masquerade(chan, rchan); /* Setup the extensions and such */ @@ -784,7 +784,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st l = strlen(xferto); snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */ - newchan = ast_feature_request_and_dial(transferer, "Local", ast_best_codec(transferer->nativeformats), + newchan = ast_feature_request_and_dial(transferer, "Local", ast_channel_best_codec(transferer), xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name); ast_indicate(transferer, -1); if (!newchan) { @@ -831,8 +831,8 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st return -1; } /* Make formats okay */ - xferchan->readformat = transferee->readformat; - xferchan->writeformat = transferee->writeformat; + xferchan->readformat = ast_get_read_format(transferee); + xferchan->writeformat = ast_get_write_format(transferee); ast_channel_masquerade(xferchan, transferee); ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority); xferchan->_state = AST_STATE_UP; diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index 96e24a4..bfe6790 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -313,7 +313,7 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params) state->pos = ast_random() % class->total_files; } - state->origwfmt = chan->writeformat; + state->origwfmt = ast_get_write_format(chan); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on %s\n", class->name, chan->name); @@ -689,7 +689,7 @@ static void *moh_alloc(struct ast_channel *chan, void *params) struct mohclass *class = params; if ((res = mohalloc(class))) { - res->origwfmt = chan->writeformat; + res->origwfmt = ast_get_write_format(chan); if (ast_set_write_format(chan, class->format)) { ast_log(LOG_WARNING, "Unable to set channel '%s' to format '%s'\n", chan->name, ast_codec2str(class->format)); moh_release(NULL, res);