FS-9020 Avmd internal/external channel

Implement checking of proper configuration
of avmd session being started on internal/external
channels. Check for read/write codec, CF_MEDIA_SET.
This commit is contained in:
Piotr Gregor 2016-04-06 16:12:39 +01:00
parent f4bca18a90
commit 73cc5ae3c1
3 changed files with 85 additions and 22 deletions

View File

@ -1359,6 +1359,8 @@ CF_STOP_BROADCAST - Signal to stop broadcast
CF_AUDIO_PAUSE - Audio is not ready to read/write CF_AUDIO_PAUSE - Audio is not ready to read/write
CF_VIDEO_PAUSE - Video is not ready to read/write CF_VIDEO_PAUSE - Video is not ready to read/write
CF_MEDIA_SET - Session has read codec assigned
</pre> </pre>
*/ */

View File

@ -12,7 +12,7 @@
/* define/undefine this to enable/disable printing of avmd /* define/undefine this to enable/disable printing of avmd
* intermediate computations to log */ * intermediate computations to log */
/*#define AVMD_DEBUG */ /*#define AVMD_DEBUG*/
/* define/undef this to enable/disable reporting of beep /* define/undef this to enable/disable reporting of beep
* detection status after session ended */ * detection status after session ended */
@ -38,11 +38,11 @@
* in the range x=[0,PI/2] */ * in the range x=[0,PI/2] */
#define AVMD_SIMPLIFIED_ESTIMATION #define AVMD_SIMPLIFIED_ESTIMATION
/* define/undefine to enable/disable avmd on incoming audio */ /* define/undefine to enable/disable avmd on internal channel */
#define AVMD_INBOUND_CHANNEL /*#define AVMD_INBOUND_CHANNEL*/
/* define/undefine to enable/disable avmd on outgoing audio */ /* define/undefine to enable/disable avmd on external channel */
/*#define AVMD_OUTBOUND_CHANNEL*/ #define AVMD_OUTBOUND_CHANNEL
#endif /* __AVMD_OPTIONS_H__ */ #endif /* __AVMD_OPTIONS_H__ */

View File

@ -206,7 +206,12 @@ static switch_bool_t avmd_callback(switch_media_bug_t * bug,
void *user_data, switch_abc_type_t type) void *user_data, switch_abc_type_t type)
{ {
avmd_session_t *avmd_session; avmd_session_t *avmd_session;
#ifdef AVMD_OUTBOUND_CHANNEL
switch_codec_t *read_codec; switch_codec_t *read_codec;
#endif
#ifdef AVMD_INBOUND_CHANNEL
switch_codec_t *write_codec;
#endif
switch_frame_t *frame; switch_frame_t *frame;
switch_core_session_t *fs_session; switch_core_session_t *fs_session;
@ -227,20 +232,39 @@ static switch_bool_t avmd_callback(switch_media_bug_t * bug,
switch (type) { switch (type) {
case SWITCH_ABC_TYPE_INIT: case SWITCH_ABC_TYPE_INIT:
#ifdef AVMD_OUTBOUND_CHANNEL
read_codec = switch_core_session_get_read_codec(fs_session); read_codec = switch_core_session_get_read_codec(fs_session);
if (read_codec == NULL) { if (read_codec == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_WARNING, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_WARNING,
"No codec assigned, default session rate to 8000 samples/s\n"); "No read codec assigned, default session rate to 8000 samples/s\n");
avmd_session->rate = 8000; avmd_session->rate = 8000;
} else { } else {
if (read_codec->implementation == NULL) { if (read_codec->implementation == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_WARNING, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_WARNING,
"No codec implementation assigned, default session rate to 8000 samples/s\n"); "No read codec implementation assigned, default session rate to 8000 samples/s\n");
avmd_session->rate = 8000; avmd_session->rate = 8000;
} else { } else {
avmd_session->rate = read_codec->implementation->samples_per_second; avmd_session->rate = read_codec->implementation->samples_per_second;
} }
} }
#endif
#ifdef AVMD_INBOUND_CHANNEL
write_codec = switch_core_session_get_write_codec(fs_session);
if (write_codec == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_WARNING,
"No write codec assigned, default session rate to 8000 samples/s\n");
avmd_session->rate = 8000;
} else {
if (write_codec->implementation == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_WARNING,
"No write codec implementation assigned, default session rate to 8000 samples/s\n");
avmd_session->rate = 8000;
} else {
avmd_session->rate = write_codec->implementation->samples_per_second;
}
}
#endif
avmd_session->start_time = switch_micro_time_now(); avmd_session->start_time = switch_micro_time_now();
/* avmd_session->vmd_codec.channels = /* avmd_session->vmd_codec.channels =
* read_codec->implementation->number_of_channels; */ * read_codec->implementation->number_of_channels; */
@ -473,7 +497,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown)
} }
/*! \brief FreeSWITCH API handler function. /*! \brief FreeSWITCH API handler function.
* This function handles API calls such as the ones from mod_event_socket and in some cases * This function handles API calls such as the ones
* from mod_event_socket and in some cases
* scripts such as LUA scripts. * scripts such as LUA scripts.
* *
* @author Eric des Courtis * @author Eric des Courtis
@ -527,9 +552,56 @@ SWITCH_STANDARD_API(avmd_api_main)
} }
/* Get current channel of the session to tag the session /* Get current channel of the session to tag the session
* This indicates that our module is present */ * This indicates that our module is present
* At this moment this cannot return NULL, it will either
* succeed or assert failed, but we make ourself secure anyway */
channel = switch_core_session_get_channel(fs_session); channel = switch_core_session_get_channel(fs_session);
if (channel == NULL) {
stream->write_function(stream, "-ERR, no channel for FreeSWITCH session [%s]!"
"\nPlease report this to the developers.\n\n", uuid);
goto end;
}
#ifdef AVMD_OUTBOUND_CHANNEL
if (SWITCH_CALL_DIRECTION_OUTBOUND != switch_channel_direction(channel)) {
stream->write_function(stream, "-ERR, channel for FreeSWITCH session [%s]"
"\nis not outbound.\n\n", uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"Channel [%s] is not outbound!\n", switch_channel_get_name(channel));
} else {
flags |= SMBF_READ_REPLACE;
}
#endif
#ifdef AVMD_INBOUND_CHANNEL
if (SWITCH_CALL_DIRECTION_INBOUND != switch_channel_direction(channel)) {
stream->write_function(stream, "-ERR, channel for FreeSWITCH session [%s]"
"\nis not inbound.\n\n", uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"Channel [%s] is not inbound!\n", switch_channel_get_name(channel));
} else {
flags |= SMBF_WRITE_REPLACE;
}
#endif
if(flags == 0) {
stream->write_function(stream, "-ERR, can't set direction for channel [%s]\n"
" for FreeSWITCH session [%s]. Please check avmd configuration.\n\n",
switch_channel_get_name(channel), uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Can't set direction for channel [%s]\n", switch_channel_get_name(channel));
goto end;
}
#ifdef AVMD_OUTBOUND_CHANNEL
if (switch_channel_test_flag(channel, CF_MEDIA_SET) == 0) {
stream->write_function(stream, "-ERR, channel [%s] for FreeSWITCH session [%s]"
"\nhas no read codec assigned yet. Please try again.\n\n",
switch_channel_get_name(channel), uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Failed to start session. Channel [%s] has no codec assigned yet.\n",
switch_channel_get_name(channel));
goto end;
}
#endif
/* Is this channel already set? */ /* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_avmd_"); bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_avmd_");
/* If yes */ /* If yes */
@ -544,11 +616,8 @@ SWITCH_STANDARD_API(avmd_api_main)
} }
/* We have already started */ /* We have already started */
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
SWITCH_CHANNEL_SESSION_LOG(session), "Cannot run 2 at once on the same channel!\n");
SWITCH_LOG_WARNING,
"Cannot run 2 at once on the same channel!\n"
);
goto end; goto end;
} }
@ -567,14 +636,6 @@ SWITCH_STANDARD_API(avmd_api_main)
init_avmd_session_data(avmd_session, fs_session); init_avmd_session_data(avmd_session, fs_session);
#ifdef AVMD_INBOUND_CHANNEL
flags |= SMBF_READ_REPLACE;
#endif
#ifdef AVMD_OUTBOUND_CHANNEL
flags |= SMBF_WRITE_REPLACE;
#endif
switch_assert(flags != 0);
/* Add a media bug that allows me to intercept the /* Add a media bug that allows me to intercept the
* reading leg of the audio stream */ * reading leg of the audio stream */
status = switch_core_media_bug_add( status = switch_core_media_bug_add(