mirror of
https://github.com/asterisk/asterisk.git
synced 2025-08-28 09:00:58 +00:00
Compare commits
7 Commits
1.6.0.27-r
...
1.6.0.27
Author | SHA1 | Date | |
---|---|---|---|
|
ff92a77fad | ||
|
88b82b5f87 | ||
|
5d2176466d | ||
|
71850d4083 | ||
|
8151c62e9e | ||
|
1790abab73 | ||
|
fd51281664 |
24
ChangeLog
24
ChangeLog
@@ -1,3 +1,27 @@
|
||||
2010-05-03 Leif Madsen <lmadsen@digium.com>
|
||||
|
||||
* Asterisk 1.6.0.27 Released
|
||||
|
||||
2010-04-29 Leif Madsen <lmadsen@digium.com>
|
||||
|
||||
* Astersik 1.6.0.27-rc3 Released
|
||||
|
||||
2010-04-29 10:31 +0000 [r260053] David Vossel <dvossel@digium.com>
|
||||
|
||||
* include/asterisk/audiohook.h, main/audiohook.c: Fixes crash in
|
||||
audiohook_write_list. (closes issue 0017052) Reported by: dvossel
|
||||
Tested by: dvossel. (closes issue 0016196) Reported by: atis.
|
||||
Review: https://reviewboard.asterisk.org/r/623/
|
||||
|
||||
2010-04-28 10:31 +0000 [r259936] David Vossel <dvossel@digium.com>
|
||||
|
||||
* channels/chan_local.c, main/channel.c: Resolves deadlocks in
|
||||
chan_local. (closes issue 0017185) Reported by: schmoozecom
|
||||
Patches: issue_17185_v1.diff uploaded by dvossel (license 671)
|
||||
issue_17185_v2.diff uploaded by dvossel (license 671) Tested
|
||||
by: schmoozecom, GameGamer43
|
||||
Review: https://reviewboard.asterisk.org/r/631/
|
||||
|
||||
2010-04-13 Leif Madsen <lmadsen@digium.com>
|
||||
|
||||
* Asterisk 1.6.0.27-rc2 Released
|
||||
|
@@ -540,12 +540,12 @@ static int local_hangup(struct ast_channel *ast)
|
||||
/* Deadlock avoidance */
|
||||
while (p->owner && ast_channel_trylock(p->owner)) {
|
||||
ast_mutex_unlock(&p->lock);
|
||||
if (ast) {
|
||||
ast_channel_unlock(ast);
|
||||
if (p->chan) {
|
||||
ast_channel_unlock(p->chan);
|
||||
}
|
||||
usleep(1);
|
||||
if (ast) {
|
||||
ast_channel_lock(ast);
|
||||
if (p->chan) {
|
||||
ast_channel_lock(p->chan);
|
||||
}
|
||||
ast_mutex_lock(&p->lock);
|
||||
}
|
||||
@@ -560,8 +560,17 @@ static int local_hangup(struct ast_channel *ast)
|
||||
} else {
|
||||
ast_module_user_remove(p->u_owner);
|
||||
while (p->chan && ast_channel_trylock(p->chan)) {
|
||||
DEADLOCK_AVOIDANCE(&p->lock);
|
||||
ast_mutex_unlock(&p->lock);
|
||||
if (p->owner) {
|
||||
ast_channel_unlock(p->owner);
|
||||
}
|
||||
usleep(1);
|
||||
if (p->owner) {
|
||||
ast_channel_lock(p->owner);
|
||||
}
|
||||
ast_mutex_lock(&p->lock);
|
||||
}
|
||||
|
||||
p->owner = NULL;
|
||||
if (p->chan) {
|
||||
ast_queue_hangup(p->chan);
|
||||
|
@@ -73,9 +73,16 @@ struct ast_audiohook;
|
||||
* \param chan Channel
|
||||
* \param frame Frame of audio to manipulate
|
||||
* \param direction Direction frame came from
|
||||
* \return Returns 0 on success, -1 on failure
|
||||
* \note An audiohook does not have any reference to a private data structure for manipulate types. It is up to the manipulate callback to store this data
|
||||
* via it's own method. An example would be datastores.
|
||||
* \return Returns 0 on success, -1 on failure.
|
||||
* \note An audiohook does not have any reference to a private data structure for manipulate
|
||||
* types. It is up to the manipulate callback to store this data via it's own method.
|
||||
* An example would be datastores.
|
||||
* \note The input frame should never be freed or corrupted during a manipulate callback.
|
||||
* If the callback has the potential to corrupt the frame's data during manipulation,
|
||||
* local data should be used for the manipulation and only copied to the frame on
|
||||
* success.
|
||||
* \note A failure return value indicates that the frame was not manipulated and that
|
||||
* is being returned in its original state.
|
||||
*/
|
||||
typedef int (*ast_audiohook_manipulate_callback)(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction);
|
||||
|
||||
|
@@ -572,7 +572,29 @@ static struct ast_frame *dtmf_audiohook_write_list(struct ast_channel *chan, str
|
||||
return frame;
|
||||
}
|
||||
|
||||
/*! \brief Pass an AUDIO frame off to be handled by the audiohook core
|
||||
/*!
|
||||
* \brief Pass an AUDIO frame off to be handled by the audiohook core
|
||||
*
|
||||
* \details
|
||||
* This function has 3 ast_frames and 3 parts to handle each. At the beginning of this
|
||||
* function all 3 frames, start_frame, middle_frame, and end_frame point to the initial
|
||||
* input frame.
|
||||
*
|
||||
* Part_1: Translate the start_frame into SLINEAR audio if it is not already in that
|
||||
* format. The result of this part is middle_frame is guaranteed to be in
|
||||
* SLINEAR format for Part_2.
|
||||
* Part_2: Send middle_frame off to spies and manipulators. At this point middle_frame is
|
||||
* either a new frame as result of the translation, or points directly to the start_frame
|
||||
* because no translation to SLINEAR audio was required. The result of this part
|
||||
* is end_frame will be updated to point to middle_frame if any audiohook manipulation
|
||||
* took place.
|
||||
* Part_3: Translate end_frame's audio back into the format of start frame if necessary.
|
||||
* At this point if middle_frame != end_frame, we are guaranteed that no manipulation
|
||||
* took place and middle_frame can be freed as it was translated... If middle_frame was
|
||||
* not translated and still pointed to start_frame, it would be equal to end_frame as well
|
||||
* regardless if manipulation took place which would not result in this free. The result
|
||||
* of this part is end_frame is guaranteed to be the format of start_frame for the return.
|
||||
*
|
||||
* \param chan Channel that the list is coming off of
|
||||
* \param audiohook_list List of audiohooks
|
||||
* \param direction Direction frame is coming in from
|
||||
@@ -587,6 +609,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
|
||||
struct ast_audiohook *audiohook = NULL;
|
||||
int samples = frame->samples;
|
||||
|
||||
/* ---Part_1. translate start_frame to SLINEAR if necessary. */
|
||||
/* If the frame coming in is not signed linear we have to send it through the in_translate path */
|
||||
if (frame->subclass != AST_FORMAT_SLINEAR) {
|
||||
if (in_translate->format != frame->subclass) {
|
||||
@@ -601,6 +624,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
|
||||
samples = middle_frame->samples;
|
||||
}
|
||||
|
||||
/* ---Part_2: Send middle_frame to spy and manipulator lists. middle_frame is guaranteed to be SLINEAR here.*/
|
||||
/* Queue up signed linear frame to each spy */
|
||||
AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
|
||||
ast_audiohook_lock(audiohook);
|
||||
@@ -654,20 +678,21 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
|
||||
audiohook->manipulate_callback(audiohook, chan, NULL, direction);
|
||||
continue;
|
||||
}
|
||||
/* Feed in frame to manipulation */
|
||||
/* Feed in frame to manipulation. */
|
||||
if (audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
|
||||
ast_frfree(middle_frame);
|
||||
middle_frame = NULL;
|
||||
/* XXX IGNORE FAILURE */
|
||||
|
||||
/* If the manipulation fails then the frame will be returned in its original state.
|
||||
* Since there are potentially more manipulator callbacks in the list, no action should
|
||||
* be taken here to exit early. */
|
||||
}
|
||||
ast_audiohook_unlock(audiohook);
|
||||
}
|
||||
AST_LIST_TRAVERSE_SAFE_END
|
||||
if (middle_frame) {
|
||||
end_frame = middle_frame;
|
||||
}
|
||||
end_frame = middle_frame;
|
||||
}
|
||||
|
||||
/* Now we figure out what to do with our end frame (whether to transcode or not) */
|
||||
/* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
|
||||
if (middle_frame == end_frame) {
|
||||
/* Middle frame was modified and became the end frame... let's see if we need to transcode */
|
||||
if (end_frame->subclass != start_frame->subclass) {
|
||||
@@ -692,9 +717,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
|
||||
}
|
||||
} else {
|
||||
/* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
|
||||
if (middle_frame) {
|
||||
ast_frfree(middle_frame);
|
||||
}
|
||||
ast_frfree(middle_frame);
|
||||
}
|
||||
|
||||
return end_frame;
|
||||
|
@@ -1986,25 +1986,22 @@ int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen,
|
||||
int res = 0;
|
||||
|
||||
ast_channel_lock(chan);
|
||||
|
||||
if (chan->generatordata) {
|
||||
if (chan->generator && chan->generator->release)
|
||||
chan->generator->release(chan, chan->generatordata);
|
||||
chan->generatordata = NULL;
|
||||
}
|
||||
|
||||
ast_prod(chan);
|
||||
if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
|
||||
res = -1;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
ast_settimeout(chan, 160, generator_force, chan);
|
||||
chan->generator = gen;
|
||||
}
|
||||
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
ast_prod(chan);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user