core framework for reverse media bugs

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4105 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2007-01-31 23:09:33 +00:00
parent d863d8dac9
commit 59ed99a9a8
5 changed files with 100 additions and 6 deletions

View File

@ -136,6 +136,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t
*/
SWITCH_DECLARE(void *) switch_core_media_bug_get_user_data(switch_media_bug_t *bug);
/*!
\brief Obtain a replace frame from a media bug
\param bug the bug to get the data from
*/
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_replace_frame(switch_media_bug_t *bug);
/*!
\brief Set a return replace frame
\param bug the bug to set the frame on
\param frame the frame to set
*/
SWITCH_DECLARE(void) switch_core_media_bug_set_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame);
/*!
\brief Remove a media bug from the session
\param session the session to remove the bug from

View File

@ -140,6 +140,7 @@ typedef enum {
SWITCH_ABC_TYPE_INIT,
SWITCH_ABC_TYPE_READ,
SWITCH_ABC_TYPE_WRITE,
SWITCH_ABC_TYPE_WRITE_REPLACE,
SWITCH_ABC_TYPE_CLOSE,
} switch_abc_type_t;
@ -654,12 +655,14 @@ typedef enum {
<pre>
SMBF_READ_STREAM - Include the Read Stream
SMBF_WRITE_STREAM - Include the Write Stream
SMBF_WRITE_STREAM - Replace the Write Stream
</pre>
*/
typedef enum {
SMBF_BOTH = 0,
SMBF_READ_STREAM = (1 << 0),
SMBF_WRITE_STREAM = (1 << 1)
SMBF_WRITE_STREAM = (1 << 1),
SMBF_WRITE_REPLACE = (1 << 2)
} switch_media_bug_flag_t;
/*!

View File

@ -231,6 +231,39 @@ static void tts_function(switch_core_session_t *session, char *data)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Done\n");
}
static void bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
switch_frame_t *frame;
switch(type) {
case SWITCH_ABC_TYPE_WRITE_REPLACE:
frame = switch_core_media_bug_get_replace_frame(bug);
switch_core_media_bug_set_replace_frame(bug, frame);
printf("W00t\n");
break;
default:
break;
}
}
static void bugtest_function(switch_core_session_t *session, char *data)
{
switch_media_bug_t *bug;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status;
if ((status = switch_core_media_bug_add(session,
bug_callback,
NULL,
SMBF_WRITE_REPLACE,
&bug)) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return;
}
switch_ivr_play_file(session, NULL, data, NULL);
}
#if 1
static void asrtest_function(switch_core_session_t *session, char *data)
{
@ -423,11 +456,18 @@ static const switch_state_handler_table_t state_handlers = {
static const switch_application_interface_t bug_application_interface = {
/*.interface_name */ "bugtest",
/*.application_function */ bugtest_function,
NULL, NULL, NULL,
/*.next*/ NULL
};
static const switch_application_interface_t ivr_application_interface = {
/*.interface_name */ "ivrmenu",
/*.application_function */ ivr_application_function,
NULL, NULL, NULL,
/*.next*/ NULL
/*.next*/ &bug_application_interface
};
static const switch_application_interface_t xml_application_interface = {

View File

@ -59,6 +59,8 @@
struct switch_media_bug {
switch_buffer_t *raw_write_buffer;
switch_buffer_t *raw_read_buffer;
switch_frame_t *replace_frame_in;
switch_frame_t *replace_frame_out;
switch_media_bug_callback_t callback;
switch_mutex_t *read_mutex;
switch_mutex_t *write_mutex;
@ -176,6 +178,17 @@ static void switch_core_media_bug_destroy(switch_media_bug_t *bug)
switch_buffer_destroy(&bug->raw_write_buffer);
}
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_replace_frame(switch_media_bug_t *bug)
{
return bug->replace_frame_in;
}
SWITCH_DECLARE(void) switch_core_media_bug_set_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame)
{
bug->replace_frame_out = frame;
}
SWITCH_DECLARE(void *) switch_core_media_bug_get_user_data(switch_media_bug_t *bug)
{
return bug->user_data;
@ -277,9 +290,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t
switch_media_bug_t **new_bug)
{
switch_media_bug_t *bug;
switch_media_bug_t *bug, *bp;
switch_size_t bytes;
if (flags & SMBF_WRITE_REPLACE) {
switch_thread_rwlock_wrlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
switch_thread_rwlock_unlock(session->bug_rwlock);
return SWITCH_STATUS_GENERR;
}
}
switch_thread_rwlock_unlock(session->bug_rwlock);
}
if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) {
return SWITCH_STATUS_MEMERR;
}
@ -2087,6 +2112,7 @@ static switch_status_t perform_write(switch_core_session_t *session, switch_fram
switch_status_t status = SWITCH_STATUS_FALSE;
if (session->endpoint_interface->io_routines->write_frame) {
if ((status =
session->endpoint_interface->io_routines->write_frame(session, frame, timeout, flags,
stream_id)) == SWITCH_STATUS_SUCCESS) {
@ -2230,15 +2256,25 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
if (bp->callback) {
bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
}
} else if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
do_bugs = 0;
if (bp->callback) {
bp->replace_frame_in = frame;
bp->replace_frame_out = NULL;
bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE);
write_frame = bp->replace_frame_out;
}
}
}
switch_thread_rwlock_unlock(session->bug_rwlock);
}
if (do_bugs) {
do_write = 1;
write_frame = frame;
goto done;
do_write = 1;
write_frame = frame;
goto done;
}
if (session->write_codec) {
if (write_frame->datalen == session->write_codec->implementation->bytes_per_frame) {
perfect = TRUE;

View File

@ -563,6 +563,7 @@ static void record_callback(switch_media_bug_t *bug, void *user_data, switch_abc
}
break;
case SWITCH_ABC_TYPE_WRITE:
default:
break;
}
}
@ -787,6 +788,7 @@ static void speech_callback(switch_media_bug_t *bug, void *user_data, switch_abc
}
break;
case SWITCH_ABC_TYPE_WRITE:
default:
break;
}
}