switch_core_io.c File Reference

#include <switch.h>
#include "private/switch_core_pvt.h"

Include dependency graph for switch_core_io.c:

Go to the source code of this file.

Functions

switch_status_t switch_core_session_write_video_frame (switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
switch_status_t switch_core_session_read_video_frame (switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
switch_status_t switch_core_session_read_frame (switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
static switch_status_t perform_write (switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
switch_status_t switch_core_session_write_frame (switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
switch_status_t switch_core_session_perform_kill_channel (switch_core_session_t *session, const char *file, const char *func, int line, switch_signal_t sig)
switch_status_t switch_core_session_recv_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf)
switch_status_t switch_core_session_send_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf)
switch_status_t switch_core_session_send_dtmf_string (switch_core_session_t *session, const char *dtmf_string)
 Send DTMF to a session.

Variables

static char * SIG_NAMES []


Function Documentation

static switch_status_t perform_write ( switch_core_session_t session,
switch_frame_t frame,
switch_io_flag_t  flags,
int  stream_id 
) [static]

Definition at line 742 of file switch_core_io.c.

References switch_core_session::endpoint_interface, switch_core_session::event_hooks, switch_endpoint_interface::io_routines, switch_io_event_hook_write_frame::next, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_io_event_hook_write_frame::write_frame, and switch_io_routines::write_frame.

Referenced by switch_core_session_write_frame().

00743 {
00744         switch_io_event_hook_write_frame_t *ptr;
00745         switch_status_t status = SWITCH_STATUS_FALSE;
00746 
00747         if (session->endpoint_interface->io_routines->write_frame) {
00748 
00749                 if ((status = session->endpoint_interface->io_routines->write_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
00750                         for (ptr = session->event_hooks.write_frame; ptr; ptr = ptr->next) {
00751                                 if ((status = ptr->write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
00752                                         break;
00753                                 }
00754                         }
00755                 }
00756         }
00757 
00758         return status;
00759 }

switch_status_t switch_core_session_perform_kill_channel ( switch_core_session_t session,
const char *  file,
const char *  func,
int  line,
switch_signal_t  sig 
)

Definition at line 1327 of file switch_core_io.c.

References switch_io_event_hook_kill_channel::kill_channel, switch_io_event_hook_kill_channel::next, switch_channel_get_name(), SWITCH_CHANNEL_ID_LOG, switch_core_session_get_uuid(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

01329 {
01330         switch_io_event_hook_kill_channel_t *ptr;
01331         switch_status_t status = SWITCH_STATUS_FALSE;
01332 
01333         switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "Send signal %s [%s]\n",
01334                                           switch_channel_get_name(session->channel), SIG_NAMES[sig]);
01335 
01336         if (session->endpoint_interface->io_routines->kill_channel) {
01337                 if ((status = session->endpoint_interface->io_routines->kill_channel(session, sig)) == SWITCH_STATUS_SUCCESS) {
01338                         for (ptr = session->event_hooks.kill_channel; ptr; ptr = ptr->next) {
01339                                 if ((status = ptr->kill_channel(session, sig)) != SWITCH_STATUS_SUCCESS) {
01340                                         break;
01341                                 }
01342                         }
01343                 }
01344         }
01345         return status;
01346 }

switch_status_t switch_core_session_read_frame ( switch_core_session_t session,
switch_frame_t **  frame,
switch_io_flag_t  flags,
int  stream_id 
)

Definition at line 102 of file switch_core_io.c.

References CF_BROADCAST, CF_PROXY_MODE, CS_HIBERNATE, switch_runtime::dummy_cng_frame, runtime, switch_assert, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION, switch_channel_get_name(), switch_channel_get_state(), switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_cond_next(), switch_core_codec_ready(), switch_ivr_dmachine_ping(), SWITCH_LOG_CRIT, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

00104 {
00105         switch_io_event_hook_read_frame_t *ptr;
00106         switch_status_t status = SWITCH_STATUS_FALSE;
00107         int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0;
00108         switch_codec_implementation_t codec_impl;
00109         unsigned int flag = 0;
00110         int i;
00111 
00112         switch_assert(session != NULL);
00113 
00114 
00115         if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) {
00116                 switch_mutex_unlock(session->codec_read_mutex);
00117         } else {
00118                 switch_cond_next();
00119                 *frame = &runtime.dummy_cng_frame;
00120                 return SWITCH_STATUS_SUCCESS;
00121         }
00122 
00123         if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) {
00124                 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_get_state(session->channel) == CS_HIBERNATE) {
00125                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n",
00126                                                           switch_channel_get_name(session->channel));
00127                         switch_cond_next();
00128                         *frame = &runtime.dummy_cng_frame;
00129                         return SWITCH_STATUS_SUCCESS;
00130                 }
00131                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
00132                 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
00133                 return SWITCH_STATUS_FALSE;
00134         }
00135 
00136         switch_mutex_lock(session->codec_read_mutex);
00137 
00138         if (!switch_core_codec_ready(session->read_codec)) {
00139                 switch_mutex_unlock(session->codec_read_mutex);
00140                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
00141                 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
00142                 *frame = &runtime.dummy_cng_frame;
00143         return SWITCH_STATUS_FALSE;
00144         }
00145 
00146         switch_mutex_lock(session->read_codec->mutex);
00147 
00148   top:
00149         
00150         for(i = 0; i < 2; i++) {
00151                 if (session->dmachine[i] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
00152                         switch_ivr_dmachine_ping(session->dmachine[i], NULL);
00153                 }
00154         }
00155         
00156         if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) {
00157                 *frame = NULL;
00158                 status = SWITCH_STATUS_FALSE;
00159                 goto even_more_done;
00160         }
00161 
00162 
00163         status = SWITCH_STATUS_FALSE;
00164         need_codec = perfect = 0;
00165 
00166         *frame = NULL;
00167 
00168         if (session->read_codec && !session->track_id && session->track_duration) {
00169                 if (session->read_frame_count == 0) {
00170                         switch_event_t *event;
00171                         session->read_frame_count = (session->read_impl.actual_samples_per_second / session->read_impl.samples_per_packet) * session->track_duration;
00172 
00173                         switch_event_create(&event, SWITCH_EVENT_SESSION_HEARTBEAT);
00174                         switch_channel_event_set_data(session->channel, event);
00175                         switch_event_fire(&event);
00176                 } else {
00177                         session->read_frame_count--;
00178                 }
00179         }
00180 
00181 
00182         if (switch_channel_test_flag(session->channel, CF_HOLD)) {
00183                 switch_yield(session->read_impl.microseconds_per_packet);
00184                 status = SWITCH_STATUS_BREAK;
00185                 goto even_more_done;
00186         }
00187 
00188         if (session->endpoint_interface->io_routines->read_frame) {
00189                 switch_mutex_unlock(session->read_codec->mutex);
00190                 switch_mutex_unlock(session->codec_read_mutex);
00191                 if ((status = session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
00192                         for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) {
00193                                 if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
00194                                         break;
00195                                 }
00196                         }
00197                 }
00198 
00199                 if (!SWITCH_READ_ACCEPTABLE(status) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) {
00200                         *frame = NULL;
00201                         return SWITCH_STATUS_FALSE;
00202                 }
00203 
00204                 switch_mutex_lock(session->codec_read_mutex);
00205 
00206                 if (!switch_core_codec_ready(session->read_codec)) {
00207                         switch_mutex_unlock(session->codec_read_mutex);
00208                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
00209                         switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
00210                         *frame = &runtime.dummy_cng_frame;
00211                         return SWITCH_STATUS_FALSE;
00212                 }
00213 
00214                 switch_mutex_lock(session->read_codec->mutex);
00215                 if (!switch_core_codec_ready(session->read_codec)) {
00216                         *frame = NULL;
00217                         status = SWITCH_STATUS_FALSE;
00218                         goto even_more_done;                    
00219                 }
00220 
00221         }
00222 
00223         if (status != SWITCH_STATUS_SUCCESS) {
00224                 goto done;
00225         }
00226 
00227         if (!(*frame)) {
00228                 goto done;
00229         }
00230 
00231         switch_assert(*frame != NULL);
00232 
00233         if (switch_test_flag(*frame, SFF_PROXY_PACKET)) {
00234                 /* Fast PASS! */
00235                 status = SWITCH_STATUS_SUCCESS;
00236                 goto done;
00237         }
00238 
00239         switch_assert((*frame)->codec != NULL);
00240 
00241         if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) {
00242                 status = SWITCH_STATUS_FALSE;
00243                 goto done;
00244         }
00245 
00246         codec_impl = *(*frame)->codec->implementation;
00247 
00248         if (session->read_codec->implementation->impl_id != codec_impl.impl_id) {
00249                 need_codec = TRUE;
00250         } 
00251         
00252         if (codec_impl.actual_samples_per_second != session->read_impl.actual_samples_per_second) {
00253                 do_resample = 1;
00254         }
00255 
00256         if (session->bugs && !need_codec) {
00257                 do_bugs = 1;
00258                 need_codec = 1;
00259         }
00260 
00261         if (switch_test_flag(*frame, SFF_CNG)) {
00262                 if (!session->bugs && !session->plc) {
00263                         /* Check if other session has bugs */
00264                         unsigned int other_session_bugs = 0;
00265                         switch_core_session_t *other_session = NULL;
00266                         if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_BRIDGED) &&
00267                                 switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
00268                                 if (other_session->bugs) {
00269                                         other_session_bugs = 1;
00270                                 }
00271                                 switch_core_session_rwunlock(other_session);
00272                         }
00273 
00274                         /* Don't process CNG frame */
00275                         if (!other_session_bugs) {
00276                                 status = SWITCH_STATUS_SUCCESS;
00277                                 goto done;
00278                         }
00279                 }
00280                 is_cng = 1;
00281                 need_codec = 1;
00282         } else if (switch_test_flag(*frame, SFF_NOT_AUDIO)) {
00283                 do_resample = 0;
00284                 do_bugs = 0;
00285                 need_codec = 0;
00286         }
00287 
00288 
00289         if (switch_test_flag(session, SSF_READ_TRANSCODE) && !need_codec && switch_core_codec_ready(session->read_codec)) {
00290                 switch_core_session_t *other_session;
00291                 const char *uuid = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_SIGNAL_BOND_VARIABLE);
00292                 switch_clear_flag(session, SSF_READ_TRANSCODE);
00293                 
00294                 if (uuid && (other_session = switch_core_session_locate(uuid))) {
00295                         switch_set_flag(other_session, SSF_READ_CODEC_RESET);
00296                         switch_set_flag(other_session, SSF_READ_CODEC_RESET);
00297                         switch_set_flag(other_session, SSF_WRITE_CODEC_RESET);
00298                         switch_core_session_rwunlock(other_session);
00299                 }
00300         }
00301 
00302         if (switch_test_flag(session, SSF_READ_CODEC_RESET)) {
00303                 switch_core_codec_reset(session->read_codec);
00304                 switch_clear_flag(session, SSF_READ_CODEC_RESET);
00305         }
00306 
00307         
00308 
00309 
00310 
00311 
00312         if (status == SWITCH_STATUS_SUCCESS && need_codec) {
00313                 switch_frame_t *enc_frame, *read_frame = *frame;
00314 
00315                 switch_set_flag(session, SSF_READ_TRANSCODE);
00316 
00317                 if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
00318                         switch_core_session_message_t msg = { 0 };
00319 
00320                         msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;
00321                         switch_core_session_receive_message(session, &msg);
00322                         switch_set_flag(session, SSF_WARN_TRANSCODE);
00323                 }
00324 
00325                 if (read_frame->codec || is_cng) {
00326                         session->raw_read_frame.datalen = session->raw_read_frame.buflen;
00327 
00328                         if (is_cng) {
00329                                 if (session->plc) {
00330                                         plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2);
00331                                         is_cng = 0;
00332                                         flag &= !SFF_CNG;
00333                                 } else {
00334                                         memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet);
00335                                 }
00336 
00337                                 session->raw_read_frame.timestamp = 0;
00338                                 session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet;
00339                                 session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
00340                                 read_frame = &session->raw_read_frame;
00341                                 status = SWITCH_STATUS_SUCCESS;
00342                         } else {
00343                                 switch_codec_t *use_codec = read_frame->codec;
00344                                 if (do_bugs) {
00345                                         switch_thread_rwlock_wrlock(session->bug_rwlock);
00346                                         if (!session->bugs) {
00347                                                 do_bugs = 0;
00348                                                 switch_thread_rwlock_unlock(session->bug_rwlock);
00349                                                 goto done;
00350                                         }
00351 
00352                                         if (!switch_core_codec_ready(&session->bug_codec)) {
00353                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting BUG Codec %s:%d\n",
00354                                                         read_frame->codec->implementation->iananame, read_frame->codec->implementation->ianacode);
00355                                                 switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL);
00356                                         }
00357                                         use_codec = &session->bug_codec;
00358                                         switch_thread_rwlock_unlock(session->bug_rwlock);
00359 
00360                                         switch_thread_rwlock_wrlock(session->bug_rwlock);
00361                                         if (!session->bugs) {
00362                                                 do_bugs = 0;
00363                                         }
00364                                         switch_thread_rwlock_unlock(session->bug_rwlock);
00365                                         if (!do_bugs) goto done;
00366                                 }
00367 
00368                                 if (switch_test_flag(read_frame, SFF_PLC)) {
00369                                         session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet;
00370                                         session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
00371                                         memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen);
00372                                         status = SWITCH_STATUS_SUCCESS;
00373                                 } else {
00374                                         switch_thread_rwlock_rdlock(session->bug_rwlock);
00375                                         status = switch_core_codec_decode(use_codec->implementation?use_codec:read_frame->codec,
00376                                                                                                           session->read_codec,
00377                                                                                                           read_frame->data,
00378                                                                                                           read_frame->datalen,
00379                                                                                                           session->read_impl.actual_samples_per_second,
00380                                                                                                           session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, 
00381                                                                                                           &read_frame->flags);
00382                                         switch_thread_rwlock_unlock(session->bug_rwlock);
00383 
00384                                 }
00385                                 
00386                                 if (status == SWITCH_STATUS_SUCCESS) {
00387                                         if ((switch_channel_test_flag(session->channel, CF_JITTERBUFFER_PLC) || switch_channel_test_flag(session->channel, CF_CNG_PLC)) 
00388                                                 && !session->plc) {
00389                                                 session->plc = plc_init(NULL);
00390                                         }
00391                                 
00392                                         if (session->plc) {
00393                                                 if (switch_test_flag(read_frame, SFF_PLC)) {
00394                                                         plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
00395                                                         switch_clear_flag(read_frame, SFF_PLC);
00396                                                 } else {
00397                                                         plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
00398                                                 }
00399                                         }
00400                                 }
00401 
00402 
00403                         }
00404 
00405                         if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) {
00406                                 status = SWITCH_STATUS_RESAMPLE;
00407                         }
00408 
00409                         switch (status) {
00410                         case SWITCH_STATUS_RESAMPLE:
00411                                 if (!session->read_resampler) {
00412                                         switch_mutex_lock(session->resample_mutex);
00413                                         status = switch_resample_create(&session->read_resampler,
00414                                                                                                         read_frame->codec->implementation->actual_samples_per_second,
00415                                                                                                         session->read_impl.actual_samples_per_second,
00416                                                                                                         session->read_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1);
00417 
00418                                         switch_mutex_unlock(session->resample_mutex);
00419 
00420                                         if (status != SWITCH_STATUS_SUCCESS) {
00421                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
00422                                                 status = SWITCH_STATUS_FALSE;
00423                                                 goto done;
00424                                         }
00425                                 }
00426                         case SWITCH_STATUS_SUCCESS:
00427                                 session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
00428                                 session->raw_read_frame.rate = read_frame->rate;
00429                                 if (read_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) {
00430                                         session->raw_read_frame.timestamp = 0;
00431                                 } else {
00432                                         session->raw_read_frame.timestamp = read_frame->timestamp;
00433                                 }
00434                                 session->raw_read_frame.ssrc = read_frame->ssrc;
00435                                 session->raw_read_frame.seq = read_frame->seq;
00436                                 session->raw_read_frame.m = read_frame->m;
00437                                 session->raw_read_frame.payload = read_frame->payload;
00438                                 session->raw_read_frame.flags = 0;
00439                                 if (switch_test_flag(read_frame, SFF_PLC)) {
00440                                         session->raw_read_frame.flags |= SFF_PLC;
00441                                 }
00442                                 read_frame = &session->raw_read_frame;
00443                                 break;
00444                         case SWITCH_STATUS_NOOP:
00445                                 if (session->read_resampler) {
00446                                         switch_mutex_lock(session->resample_mutex);
00447                                         switch_resample_destroy(&session->read_resampler);
00448                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
00449                                         switch_mutex_unlock(session->resample_mutex);
00450                                 }
00451 
00452                                 status = SWITCH_STATUS_SUCCESS;
00453                                 break;
00454                         case SWITCH_STATUS_BREAK:
00455                                 memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet);
00456                                 session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet;
00457                                 session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
00458                                 session->raw_read_frame.timestamp = read_frame->timestamp;
00459                                 session->raw_read_frame.rate = read_frame->rate;
00460                                 session->raw_read_frame.ssrc = read_frame->ssrc;
00461                                 session->raw_read_frame.seq = read_frame->seq;
00462                                 session->raw_read_frame.m = read_frame->m;
00463                                 session->raw_read_frame.payload = read_frame->payload;
00464                                 session->raw_read_frame.flags = 0;
00465                                 if (switch_test_flag(read_frame, SFF_PLC)) {
00466                                         session->raw_read_frame.flags |= SFF_PLC;
00467                                 }
00468 
00469                                 read_frame = &session->raw_read_frame;
00470                                 status = SWITCH_STATUS_SUCCESS;
00471                                 break;
00472                         case SWITCH_STATUS_NOT_INITALIZED:
00473                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
00474                                 goto done;
00475                         default:
00476                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n",
00477                                                                   session->read_codec->codec_interface->interface_name);
00478                                 goto done;
00479                         }
00480                 }
00481 
00482                 if (session->bugs) {
00483                         switch_media_bug_t *bp;
00484                         switch_bool_t ok = SWITCH_TRUE;
00485                         int prune = 0;
00486                         switch_thread_rwlock_rdlock(session->bug_rwlock);
00487 
00488                         for (bp = session->bugs; bp; bp = bp->next) {
00489                                 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
00490                                         continue;
00491                                 }
00492 
00493                                 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
00494                                         continue;
00495                                 }
00496                                 if (switch_test_flag(bp, SMBF_PRUNE)) {
00497                                         prune++;
00498                                         continue;
00499                                 }
00500 
00501                                 if (ok && switch_test_flag(bp, SMBF_READ_REPLACE)) {
00502                                         do_bugs = 0;
00503                                         if (bp->callback) {
00504                                                 bp->read_replace_frame_in = read_frame;
00505                                                 bp->read_replace_frame_out = read_frame;
00506                                                 bp->read_demux_frame = NULL;
00507                                                 if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) {
00508                                                         read_frame = bp->read_replace_frame_out;
00509                                                 }
00510                                         }
00511                                 }
00512 
00513                                 if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
00514                                         switch_set_flag(bp, SMBF_PRUNE);
00515                                         prune++;
00516                                 }
00517 
00518 
00519                         }
00520                         switch_thread_rwlock_unlock(session->bug_rwlock);
00521                         if (prune) {
00522                                 switch_core_media_bug_prune(session);
00523                         }
00524                 }
00525 
00526                 if (session->bugs) {
00527                         switch_media_bug_t *bp;
00528                         switch_bool_t ok = SWITCH_TRUE;
00529                         int prune = 0;
00530                         switch_thread_rwlock_rdlock(session->bug_rwlock);
00531 
00532                         for (bp = session->bugs; bp; bp = bp->next) {
00533                                 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
00534                                         continue;
00535                                 }
00536 
00537                                 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
00538                                         continue;
00539                                 }
00540                                 if (switch_test_flag(bp, SMBF_PRUNE)) {
00541                                         prune++;
00542                                         continue;
00543                                 }
00544 
00545                                 if (ok && bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) {
00546                                         switch_mutex_lock(bp->read_mutex);
00547                                         if (bp->read_demux_frame) {
00548                                                 uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
00549                                                 int bytes = read_frame->datalen / 2;
00550 
00551                                                 memcpy(data, read_frame->data, read_frame->datalen);
00552                                                 switch_unmerge_sln((int16_t *)data, bytes, bp->read_demux_frame->data, bytes);
00553                                                 switch_buffer_write(bp->raw_read_buffer, data, read_frame->datalen);
00554                                         } else {
00555                                                 switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen);
00556                                         }
00557 
00558                                         if (bp->callback) {
00559                                                 ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ);
00560                                         }
00561                                         switch_mutex_unlock(bp->read_mutex);
00562                                 }
00563 
00564                                 if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
00565                                         switch_set_flag(bp, SMBF_PRUNE);
00566                                         prune++;
00567                                 }
00568                         }
00569                         switch_thread_rwlock_unlock(session->bug_rwlock);
00570                         if (prune) {
00571                                 switch_core_media_bug_prune(session);
00572                         }
00573                 }
00574 
00575                 if (do_bugs) {
00576                         goto done;
00577                 }
00578 
00579                 if (session->read_codec) {
00580                         if (session->read_resampler) {
00581                                 short *data = read_frame->data;
00582                                 switch_mutex_lock(session->resample_mutex);
00583                                 switch_resample_process(session->read_resampler, data, (int) read_frame->datalen / 2);
00584                                 memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2);
00585                                 read_frame->samples = session->read_resampler->to_len;
00586                                 read_frame->datalen = session->read_resampler->to_len * 2;
00587                                 read_frame->rate = session->read_resampler->to_rate;
00588                                 switch_mutex_unlock(session->resample_mutex);
00589                         }
00590 
00591                         if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) {
00592                                 perfect = TRUE;
00593                         } else {
00594                                 if (!session->raw_read_buffer) {
00595                                         switch_size_t bytes = session->read_impl.decoded_bytes_per_packet;
00596                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n",
00597                                                                           (uint32_t) bytes, (uint32_t) (*frame)->datalen);
00598                                         switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0);
00599                                 }
00600 
00601                                 if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) {
00602                                         status = SWITCH_STATUS_MEMERR;
00603                                         goto done;
00604                                 }
00605                         }
00606 
00607                         if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) {
00608                                 if (perfect) {
00609                                         enc_frame = read_frame;
00610                                         session->raw_read_frame.rate = read_frame->rate;
00611                                 } else {
00612                                         session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer,
00613                                                                                                                                                                         session->raw_read_frame.data,
00614                                                                                                                                                                         session->read_impl.decoded_bytes_per_packet);
00615 
00616                                         session->raw_read_frame.rate = session->read_impl.actual_samples_per_second;
00617                                         enc_frame = &session->raw_read_frame;
00618                                 }
00619                                 session->enc_read_frame.datalen = session->enc_read_frame.buflen;
00620 
00621                                 switch_assert(session->read_codec != NULL);
00622                                 switch_assert(enc_frame != NULL);
00623                                 switch_assert(enc_frame->data != NULL);
00624 
00625                                 status = switch_core_codec_encode(session->read_codec,
00626                                                                                                   enc_frame->codec,
00627                                                                                                   enc_frame->data,
00628                                                                                                   enc_frame->datalen,
00629                                                                                                   session->read_impl.actual_samples_per_second,
00630                                                                                                   session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag);
00631 
00632                                 switch (status) {
00633                                 case SWITCH_STATUS_RESAMPLE:
00634                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 1\n");
00635                                 case SWITCH_STATUS_SUCCESS:
00636                                         session->enc_read_frame.samples = session->read_impl.decoded_bytes_per_packet / sizeof(int16_t);
00637                                         if (perfect) {
00638                                                 if (enc_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) {
00639                                                         session->enc_read_frame.timestamp = 0;
00640                                                 } else {
00641                                                         session->enc_read_frame.timestamp = read_frame->timestamp;
00642                                                 }
00643                                                 session->enc_read_frame.rate = read_frame->rate;
00644                                                 session->enc_read_frame.ssrc = read_frame->ssrc;
00645                                                 session->enc_read_frame.seq = read_frame->seq;
00646                                                 session->enc_read_frame.m = read_frame->m;
00647                                                 session->enc_read_frame.payload = session->read_impl.ianacode;
00648                                         }
00649                                         *frame = &session->enc_read_frame;
00650                                         break;
00651                                 case SWITCH_STATUS_NOOP:
00652                                         session->raw_read_frame.samples = enc_frame->codec->implementation->samples_per_packet;
00653                                         session->raw_read_frame.timestamp = read_frame->timestamp;
00654                                         session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode;
00655                                         session->raw_read_frame.m = read_frame->m;
00656                                         session->raw_read_frame.ssrc = read_frame->ssrc;
00657                                         session->raw_read_frame.seq = read_frame->seq;
00658                                         *frame = enc_frame;
00659                                         status = SWITCH_STATUS_SUCCESS;
00660                                         break;
00661                                 case SWITCH_STATUS_NOT_INITALIZED:
00662                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
00663                                         *frame = NULL;
00664                                         status = SWITCH_STATUS_GENERR;
00665                                         break;
00666                                 default:
00667                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
00668                                                                           session->read_codec->codec_interface->interface_name);
00669                                         *frame = NULL;
00670                                         status = SWITCH_STATUS_GENERR;
00671                                         break;
00672                                 }
00673                         } else {
00674                                 goto top;
00675                         }
00676                 }
00677         }
00678 
00679   done:
00680         if (!(*frame)) {
00681                 status = SWITCH_STATUS_FALSE;
00682         } else {
00683                 if (flag & SFF_CNG) {
00684                         switch_set_flag((*frame), SFF_CNG);
00685                 }
00686                 if (session->bugs) {
00687                         switch_media_bug_t *bp;
00688                         switch_bool_t ok = SWITCH_TRUE;
00689                         int prune = 0;
00690                         switch_thread_rwlock_rdlock(session->bug_rwlock);
00691                         for (bp = session->bugs; bp; bp = bp->next) {
00692                                 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
00693                                         continue;
00694                                 }
00695 
00696                                 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
00697                                         continue;
00698                                 }
00699 
00700                                 if (switch_test_flag(bp, SMBF_PRUNE)) {
00701                                         prune++;
00702                                         continue;
00703                                 }
00704 
00705                                 if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) {
00706                                         switch_mutex_lock(bp->read_mutex);
00707                                         bp->ping_frame = *frame;
00708                                         if (bp->callback) {
00709                                                 if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_PING) == SWITCH_FALSE
00710                                                         || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
00711                                                         ok = SWITCH_FALSE;
00712                                                 }
00713                                         }
00714                                         bp->ping_frame = NULL;;
00715                                         switch_mutex_unlock(bp->read_mutex);
00716                                 }
00717 
00718                                 if (ok == SWITCH_FALSE) {
00719                                         switch_set_flag(bp, SMBF_PRUNE);
00720                                         prune++;
00721                                 }
00722                         }
00723                         switch_thread_rwlock_unlock(session->bug_rwlock);
00724                         if (prune) {
00725                                 switch_core_media_bug_prune(session);
00726                         }
00727                 }
00728         }
00729 
00730   even_more_done:
00731 
00732         if (!*frame || !(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)) {
00733                 *frame = &runtime.dummy_cng_frame;
00734         }
00735 
00736         switch_mutex_unlock(session->read_codec->mutex);
00737         switch_mutex_unlock(session->codec_read_mutex);
00738 
00739         return status;
00740 }

switch_status_t switch_core_session_read_video_frame ( switch_core_session_t session,
switch_frame_t **  frame,
switch_io_flag_t  flags,
int  stream_id 
)

Definition at line 60 of file switch_core_io.c.

References switch_io_event_hook_video_read_frame::next, SFF_CNG, switch_assert, switch_channel_down, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, and switch_io_event_hook_video_read_frame::video_read_frame.

00062 {
00063         switch_status_t status = SWITCH_STATUS_FALSE;
00064         switch_io_event_hook_video_read_frame_t *ptr;
00065 
00066         switch_assert(session != NULL);
00067 
00068         if (switch_channel_down(session->channel)) {
00069                 return SWITCH_STATUS_FALSE;
00070         }
00071 
00072         if (session->endpoint_interface->io_routines->read_video_frame) {
00073                 if ((status = session->endpoint_interface->io_routines->read_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
00074                         for (ptr = session->event_hooks.video_read_frame; ptr; ptr = ptr->next) {
00075                                 if ((status = ptr->video_read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
00076                                         break;
00077                                 }
00078                         }
00079                 }
00080         }
00081 
00082         if (status != SWITCH_STATUS_SUCCESS) {
00083                 goto done;
00084         }
00085 
00086         if (!(*frame)) {
00087                 goto done;
00088         }
00089 
00090         switch_assert(*frame != NULL);
00091 
00092         if (switch_test_flag(*frame, SFF_CNG)) {
00093                 status = SWITCH_STATUS_SUCCESS;
00094                 goto done;
00095         }
00096 
00097   done:
00098 
00099         return status;
00100 }

switch_status_t switch_core_session_recv_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf 
)

Definition at line 1348 of file switch_core_io.c.

References CF_BROADCAST, switch_dtmf_t::digit, DTMF_FLAG_SKIP_PROCESS, switch_dtmf_t::duration, switch_io_event_hook_recv_dtmf::next, switch_io_event_hook_recv_dtmf::recv_dtmf, switch_assert, switch_channel_down, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_core_default_dtmf_duration(), switch_core_max_dtmf_duration(), switch_core_min_dtmf_duration(), SWITCH_DTMF_RECV, switch_ivr_dmachine_feed(), SWITCH_LOG_DEBUG1, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_test_flag.

01349 {
01350         switch_io_event_hook_recv_dtmf_t *ptr;
01351         switch_status_t status;
01352         switch_dtmf_t new_dtmf;
01353         int fed = 0;
01354         
01355         if (switch_channel_down(session->channel)) {
01356                 return SWITCH_STATUS_FALSE;
01357         }
01358 
01359         switch_assert(dtmf);
01360 
01361         new_dtmf = *dtmf;
01362 
01363         if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
01364                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
01365                                                   switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
01366                 new_dtmf.duration = switch_core_max_dtmf_duration(0);
01367         } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
01368                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
01369                                                   switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
01370                 new_dtmf.duration = switch_core_min_dtmf_duration(0);
01371         } else if (!new_dtmf.duration) {
01372                 new_dtmf.duration = switch_core_default_dtmf_duration(0);
01373         }
01374         
01375         if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)) {
01376                 if (session->dmachine[0] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
01377                         char str[2] = { dtmf->digit, '\0' };
01378                         switch_ivr_dmachine_feed(session->dmachine[0], str, NULL);
01379                         fed = 1;
01380                 }
01381 
01382                 for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) {
01383                         if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) {
01384                                 return status;
01385                         }
01386                 }
01387         }
01388 
01389         return fed ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
01390 }

switch_status_t switch_core_session_send_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf 
)

Definition at line 1392 of file switch_core_io.c.

References CC_QUEUEABLE_DTMF_DELAY, CF_BROADCAST, switch_dtmf_t::digit, DTMF_FLAG_SKIP_PROCESS, switch_dtmf_t::duration, switch_io_event_hook_send_dtmf::next, switch_io_event_hook_send_dtmf::send_dtmf, switch_assert, switch_channel_down, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_cap(), switch_channel_test_flag(), switch_core_default_dtmf_duration(), switch_core_max_dtmf_duration(), switch_core_min_dtmf_duration(), SWITCH_DTMF_SEND, switch_ivr_dmachine_feed(), switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, and switch_yield.

01393 {
01394         switch_io_event_hook_send_dtmf_t *ptr;
01395         switch_status_t status = SWITCH_STATUS_FALSE;
01396         switch_dtmf_t new_dtmf;
01397 
01398         if (switch_channel_down(session->channel)) {
01399                 return SWITCH_STATUS_FALSE;
01400         }
01401 
01402         switch_assert(dtmf);
01403 
01404         new_dtmf = *dtmf;
01405         
01406         if (new_dtmf.digit != 'w' && new_dtmf.digit != 'W') {
01407                 if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
01408                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
01409                                                           switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
01410                         new_dtmf.duration = switch_core_max_dtmf_duration(0);
01411                 } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
01412                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
01413                                                   switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
01414                         new_dtmf.duration = switch_core_min_dtmf_duration(0);
01415                 } 
01416         }
01417 
01418         if (!new_dtmf.duration) {
01419                 new_dtmf.duration = switch_core_default_dtmf_duration(0);
01420         }
01421 
01422         if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)) {  
01423                 for (ptr = session->event_hooks.send_dtmf; ptr; ptr = ptr->next) {
01424                         if ((status = ptr->send_dtmf(session, dtmf, SWITCH_DTMF_SEND)) != SWITCH_STATUS_SUCCESS) {
01425                                 return SWITCH_STATUS_SUCCESS;
01426                         }
01427                 }
01428 
01429                 if (session->dmachine[1] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
01430                         char str[2] = { new_dtmf.digit, '\0' };
01431                         switch_ivr_dmachine_feed(session->dmachine[1], str, NULL);
01432                         return SWITCH_STATUS_SUCCESS;
01433                 }
01434         }
01435 
01436 
01437         if (session->endpoint_interface->io_routines->send_dtmf) {
01438                 int send = 0;
01439                 status = SWITCH_STATUS_SUCCESS;
01440                 
01441                 if (switch_channel_test_cap(session->channel, CC_QUEUEABLE_DTMF_DELAY) && (dtmf->digit == 'w' || dtmf->digit == 'W')) {
01442                         send = 1;
01443                 } else {
01444                         if (dtmf->digit == 'w') {
01445                                 switch_yield(500000);
01446                         } else if (dtmf->digit == 'W') {
01447                                 switch_yield(1000000);
01448                         } else {
01449                                 send = 1;
01450                         }
01451                 }
01452 
01453                 if (send) {
01454                         status = session->endpoint_interface->io_routines->send_dtmf(session, &new_dtmf);
01455                 }
01456         }
01457         return status;
01458 }

switch_status_t switch_core_session_write_frame ( switch_core_session_t session,
switch_frame_t frame,
switch_io_flag_t  flags,
int  stream_id 
)

Definition at line 761 of file switch_core_io.c.

References switch_media_bug::callback, CF_ACCEPT_CNG, CF_ANSWERED, CF_HOLD, CF_PASSTHRU_PTIME_MISMATCH, CF_PAUSE_BUGS, switch_frame::codec, switch_frame::data, switch_buffer::data, switch_frame::datalen, switch_codec_implementation::ianacode, switch_codec::implementation, switch_frame::m, switch_core_session_message::message_id, switch_media_bug::next, switch_frame::payload, perform_write(), switch_frame::rate, switch_media_bug::raw_write_buffer, switch_media_bug::ready, switch_frame::samples, switch_frame::seq, SFF_NOT_AUDIO, SFF_PLC, SFF_PROXY_PACKET, SMBF_ANSWER_REQ, SMBF_NO_PAUSE, SMBF_PRUNE, SMBF_WRITE_REPLACE, SMBF_WRITE_STREAM, SSF_READ_CODEC_RESET, SSF_WARN_TRANSCODE, SSF_WRITE_CODEC_RESET, SSF_WRITE_TRANSCODE, switch_frame::ssrc, switch_media_bug::stop_time, SWITCH_ABC_TYPE_WRITE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_assert, SWITCH_BUFFER_BLOCK_FRAMES, switch_buffer_create_dynamic(), switch_buffer_inuse(), switch_buffer_read(), SWITCH_BUFFER_START_FRAMES, switch_buffer_write(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION, switch_channel_down, switch_channel_get_name(), switch_channel_get_variable, switch_channel_hangup, switch_channel_media_ready, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_clear_flag, SWITCH_CODEC_FLAG_PASSTHROUGH, switch_core_codec_decode(), switch_core_codec_encode(), switch_core_codec_ready(), switch_core_codec_reset(), switch_core_media_bug_flush_all(), switch_core_media_bug_prune(), switch_core_media_bug_test_flag(), switch_core_session_get_channel(), switch_core_session_locate(), switch_core_session_receive_message, switch_core_session_rwunlock(), switch_epoch_time_now(), SWITCH_FALSE, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_NOTICE, switch_log_printf(), SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY, switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), switch_resample_create, switch_resample_destroy(), switch_resample_process(), SWITCH_RESAMPLE_QUALITY, switch_set_flag, SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_MEMERR, SWITCH_STATUS_NOOP, SWITCH_STATUS_NOT_INITALIZED, SWITCH_STATUS_RESAMPLE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_rwlock_rdlock(), switch_thread_rwlock_unlock(), SWITCH_TRUE, switch_frame::timestamp, TRUE, switch_media_bug::user_data, switch_media_bug::write_mutex, switch_media_bug::write_replace_frame_in, and switch_media_bug::write_replace_frame_out.

00763 {
00764 
00765         switch_status_t status = SWITCH_STATUS_FALSE;
00766         switch_frame_t *enc_frame = NULL, *write_frame = frame;
00767         unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0, resample = 0;
00768         int did_write_resample = 0;
00769 
00770         switch_assert(session != NULL);
00771         switch_assert(frame != NULL);
00772 
00773         if (!switch_channel_ready(session->channel)) {
00774                 return SWITCH_STATUS_FALSE;
00775         }
00776 
00777         if (switch_mutex_trylock(session->codec_write_mutex) == SWITCH_STATUS_SUCCESS) {
00778                 switch_mutex_unlock(session->codec_write_mutex);
00779         } else {
00780                 return SWITCH_STATUS_SUCCESS;
00781         }
00782 
00783         if (switch_test_flag(frame, SFF_CNG)) {
00784                 if (switch_channel_test_flag(session->channel, CF_ACCEPT_CNG)) {
00785                         pass_cng = 1;
00786                 } else {
00787                         return SWITCH_STATUS_SUCCESS;
00788                 }
00789         }
00790 
00791         if (!(session->write_codec && switch_core_codec_ready(session->write_codec)) && !pass_cng) {
00792                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no write codec.\n", switch_channel_get_name(session->channel));
00793                 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
00794                 return SWITCH_STATUS_FALSE;
00795         }
00796 
00797         if (switch_channel_test_flag(session->channel, CF_HOLD)) {
00798                 return SWITCH_STATUS_SUCCESS;
00799         }
00800 
00801         if (switch_test_flag(frame, SFF_PROXY_PACKET) || pass_cng) {
00802                 /* Fast PASS! */
00803                 switch_mutex_lock(session->codec_write_mutex);
00804                 status = perform_write(session, frame, flag, stream_id);
00805                 switch_mutex_unlock(session->codec_write_mutex);
00806                 return status;
00807         }
00808 
00809         switch_mutex_lock(session->codec_write_mutex);
00810 
00811         if (!(frame->codec && frame->codec->implementation)) {
00812                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has received a bad frame with no codec!\n", 
00813                                                   switch_channel_get_name(session->channel));
00814                 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00815                 switch_mutex_unlock(session->codec_write_mutex);
00816                 return SWITCH_STATUS_FALSE;
00817         }
00818 
00819         switch_assert(frame->codec != NULL);
00820         switch_assert(frame->codec->implementation != NULL);
00821 
00822         if (!(switch_core_codec_ready(session->write_codec) && frame->codec) ||
00823                 !switch_channel_ready(session->channel) || !switch_channel_media_ready(session->channel)) {
00824                 switch_mutex_unlock(session->codec_write_mutex);
00825                 return SWITCH_STATUS_FALSE;
00826         }
00827 
00828         switch_mutex_lock(session->write_codec->mutex);
00829         switch_mutex_lock(frame->codec->mutex);
00830 
00831         if (!(switch_core_codec_ready(session->write_codec) && switch_core_codec_ready(frame->codec))) goto error;
00832         
00833         if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) {
00834                 if (session->write_impl.codec_id == frame->codec->implementation->codec_id ||
00835                         session->write_impl.microseconds_per_packet != frame->codec->implementation->microseconds_per_packet) {
00836                         ptime_mismatch = TRUE;
00837                         if ((switch_test_flag(frame->codec, SWITCH_CODEC_FLAG_PASSTHROUGH) || switch_test_flag(session->read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) ||
00838                                 switch_channel_test_flag(session->channel, CF_PASSTHRU_PTIME_MISMATCH)) {
00839                                 status = perform_write(session, frame, flags, stream_id);
00840                                 goto error;
00841                         }
00842                 }
00843                 need_codec = TRUE;
00844         }
00845 
00846         if (session->write_codec && !frame->codec) {
00847                 need_codec = TRUE;
00848         }
00849 
00850         if (session->bugs && !need_codec) {
00851                 do_bugs = TRUE;
00852                 need_codec = TRUE;
00853         }
00854 
00855         if (frame->codec->implementation->actual_samples_per_second != session->write_impl.actual_samples_per_second) {
00856                 need_codec = TRUE;
00857                 do_resample = TRUE;
00858         }
00859 
00860 
00861         if ((frame->flags & SFF_NOT_AUDIO)) {
00862                 do_resample = 0;
00863                 do_bugs = 0;
00864                 need_codec = 0;
00865         }
00866 
00867         if (switch_test_flag(session, SSF_WRITE_TRANSCODE) && !need_codec && switch_core_codec_ready(session->write_codec)) {
00868                 switch_core_session_t *other_session;
00869                 const char *uuid = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_SIGNAL_BOND_VARIABLE);
00870 
00871                 if (uuid && (other_session = switch_core_session_locate(uuid))) {
00872                         switch_set_flag(other_session, SSF_READ_CODEC_RESET);
00873                         switch_set_flag(other_session, SSF_READ_CODEC_RESET);
00874                         switch_set_flag(other_session, SSF_WRITE_CODEC_RESET);
00875                         switch_core_session_rwunlock(other_session);
00876                 }
00877                 
00878                 switch_clear_flag(session, SSF_WRITE_TRANSCODE);
00879         }
00880 
00881 
00882         if (switch_test_flag(session, SSF_WRITE_CODEC_RESET)) {
00883                 switch_core_codec_reset(session->write_codec);
00884                 switch_clear_flag(session, SSF_WRITE_CODEC_RESET);
00885         }
00886 
00887         if (!need_codec) {
00888                 do_write = TRUE;
00889                 write_frame = frame;
00890                 goto done;
00891         }
00892 
00893         if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
00894                 switch_core_session_message_t msg = { 0 };
00895 
00896                 msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;
00897                 switch_core_session_receive_message(session, &msg);
00898                 switch_set_flag(session, SSF_WARN_TRANSCODE);
00899         }
00900 
00901         if (frame->codec) {
00902                 session->raw_write_frame.datalen = session->raw_write_frame.buflen;
00903                 status = switch_core_codec_decode(frame->codec,
00904                                                                                   session->write_codec,
00905                                                                                   frame->data,
00906                                                                                   frame->datalen,
00907                                                                                   session->write_impl.actual_samples_per_second,
00908                                                                                   session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags);
00909 
00910                 if (do_resample && status == SWITCH_STATUS_SUCCESS) {
00911                         status = SWITCH_STATUS_RESAMPLE;
00912                 }
00913                 
00914                 switch (status) {
00915                 case SWITCH_STATUS_RESAMPLE:
00916                         resample++;
00917                         write_frame = &session->raw_write_frame;
00918                         write_frame->rate = frame->codec->implementation->actual_samples_per_second;
00919                         if (!session->write_resampler) {
00920                                 switch_mutex_lock(session->resample_mutex);
00921                                 status = switch_resample_create(&session->write_resampler,
00922                                                                                                 frame->codec->implementation->actual_samples_per_second,
00923                                                                                                 session->write_impl.actual_samples_per_second,
00924                                                                                                 session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1);
00925 
00926 
00927                                 switch_mutex_unlock(session->resample_mutex);
00928                                 if (status != SWITCH_STATUS_SUCCESS) {
00929                                         goto done;
00930                                 }
00931                         }
00932                         break;
00933                 case SWITCH_STATUS_SUCCESS:
00934                         session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t);
00935                         session->raw_write_frame.timestamp = frame->timestamp;
00936                         session->raw_write_frame.rate = frame->rate;
00937                         session->raw_write_frame.m = frame->m;
00938                         session->raw_write_frame.ssrc = frame->ssrc;
00939                         session->raw_write_frame.seq = frame->seq;
00940                         session->raw_write_frame.payload = frame->payload;
00941                         session->raw_write_frame.flags = 0;
00942                         if (switch_test_flag(frame, SFF_PLC)) {
00943                                 session->raw_write_frame.flags |= SFF_PLC;
00944                         }
00945 
00946                         write_frame = &session->raw_write_frame;
00947                         break;
00948                 case SWITCH_STATUS_BREAK:
00949                         status = SWITCH_STATUS_SUCCESS;
00950                         goto error;
00951                 case SWITCH_STATUS_NOOP:
00952                         if (session->write_resampler) {
00953                                 switch_mutex_lock(session->resample_mutex);
00954                                 switch_resample_destroy(&session->write_resampler);
00955                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
00956                                 switch_mutex_unlock(session->resample_mutex);
00957                         }
00958                         write_frame = frame;
00959                         status = SWITCH_STATUS_SUCCESS;
00960                         break;
00961                 default:
00962 
00963                         if (status == SWITCH_STATUS_NOT_INITALIZED) {
00964                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
00965                                 goto error;
00966                         }
00967                         if (ptime_mismatch && status != SWITCH_STATUS_GENERR) {
00968                                 status = perform_write(session, frame, flags, stream_id);
00969                                 status = SWITCH_STATUS_SUCCESS;
00970                                 goto error;
00971                         }
00972 
00973                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n",
00974                                                           frame->codec->codec_interface->interface_name);
00975                         goto error;
00976                 }
00977         }
00978         
00979 
00980 
00981         if (session->write_resampler) {
00982                 short *data = write_frame->data;
00983 
00984                 switch_mutex_lock(session->resample_mutex);
00985                 if (session->write_resampler) {
00986 
00987                         switch_resample_process(session->write_resampler, data, write_frame->datalen / 2);
00988 
00989                         memcpy(data, session->write_resampler->to, session->write_resampler->to_len * 2);
00990 
00991                         write_frame->samples = session->write_resampler->to_len;
00992 
00993                         write_frame->datalen = write_frame->samples * 2;
00994 
00995                         write_frame->rate = session->write_resampler->to_rate;
00996 
00997                         did_write_resample = 1;
00998                 }
00999                 switch_mutex_unlock(session->resample_mutex);
01000         }
01001 
01002 
01003 
01004         if (session->bugs) {
01005                 switch_media_bug_t *bp;
01006                 int prune = 0;
01007 
01008                 switch_thread_rwlock_rdlock(session->bug_rwlock);
01009                 for (bp = session->bugs; bp; bp = bp->next) {
01010                         switch_bool_t ok = SWITCH_TRUE;
01011                         if (!bp->ready) {
01012                                 continue;
01013                         }
01014 
01015                         if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
01016                                 continue;
01017                         }
01018 
01019                         if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
01020                                 continue;
01021                         }
01022 
01023                         if (switch_test_flag(bp, SMBF_PRUNE)) {
01024                                 prune++;
01025                                 continue;
01026                         }
01027 
01028                         if (switch_test_flag(bp, SMBF_WRITE_STREAM)) {
01029                                 switch_mutex_lock(bp->write_mutex);
01030                                 switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen);
01031                                 switch_mutex_unlock(bp->write_mutex);
01032                                 
01033                                 if (bp->callback) {
01034                                         ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
01035                                 }
01036                         }
01037 
01038                         if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
01039                                 do_bugs = 0;
01040                                 if (bp->callback) {
01041                                         bp->write_replace_frame_in = write_frame;
01042                                         bp->write_replace_frame_out = write_frame;
01043                                         if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) {
01044                                                 write_frame = bp->write_replace_frame_out;
01045                                         }
01046                                 }
01047                         }
01048 
01049                         if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) {
01050                                 ok = SWITCH_FALSE;
01051                         }
01052 
01053 
01054                         if (ok == SWITCH_FALSE) {
01055                                 switch_set_flag(bp, SMBF_PRUNE);
01056                                 prune++;
01057                         }
01058                 }
01059                 switch_thread_rwlock_unlock(session->bug_rwlock);
01060                 if (prune) {
01061                         switch_core_media_bug_prune(session);
01062                 }
01063         }
01064 
01065         if (do_bugs) {
01066                 do_write = TRUE;
01067                 write_frame = frame;
01068                 goto done;
01069         }
01070 
01071         if (session->write_codec) {
01072                 if (!ptime_mismatch && write_frame->codec && write_frame->codec->implementation &&
01073                         write_frame->codec->implementation->decoded_bytes_per_packet == session->write_impl.decoded_bytes_per_packet) {
01074                         perfect = TRUE;
01075                 }
01076 
01077 
01078 
01079                 if (perfect) {
01080 
01081                         if (write_frame->datalen < session->write_impl.decoded_bytes_per_packet) {
01082                                 memset(write_frame->data, 255, session->write_impl.decoded_bytes_per_packet - write_frame->datalen);
01083                                 write_frame->datalen = session->write_impl.decoded_bytes_per_packet;
01084                         }
01085 
01086                         enc_frame = write_frame;
01087                         session->enc_write_frame.datalen = session->enc_write_frame.buflen;
01088 
01089                         status = switch_core_codec_encode(session->write_codec,
01090                                                                                           frame->codec,
01091                                                                                           enc_frame->data,
01092                                                                                           enc_frame->datalen,
01093                                                                                           session->write_impl.actual_samples_per_second,
01094                                                                                           session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
01095 
01096 
01097 
01098 
01099                         switch (status) {
01100                         case SWITCH_STATUS_RESAMPLE:
01101                                 resample++;
01102                                 /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 2\n"); */
01103                         case SWITCH_STATUS_SUCCESS:
01104                                 session->enc_write_frame.codec = session->write_codec;
01105                                 session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
01106                                 if (frame->codec->implementation->samples_per_packet != session->write_impl.samples_per_packet) {
01107                                         session->enc_write_frame.timestamp = 0;
01108                                 } else {
01109                                         session->enc_write_frame.timestamp = frame->timestamp;
01110                                 }
01111                                 session->enc_write_frame.payload = session->write_impl.ianacode;
01112                                 session->enc_write_frame.m = frame->m;
01113                                 session->enc_write_frame.ssrc = frame->ssrc;
01114                                 session->enc_write_frame.seq = frame->seq;
01115                                 session->enc_write_frame.flags = 0;
01116                                 write_frame = &session->enc_write_frame;
01117                                 break;
01118                         case SWITCH_STATUS_NOOP:
01119                                 enc_frame->codec = session->write_codec;
01120                                 enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
01121                                 enc_frame->timestamp = frame->timestamp;
01122                                 enc_frame->m = frame->m;
01123                                 enc_frame->seq = frame->seq;
01124                                 enc_frame->ssrc = frame->ssrc;
01125                                 enc_frame->payload = enc_frame->codec->implementation->ianacode;
01126                                 write_frame = enc_frame;
01127                                 status = SWITCH_STATUS_SUCCESS;
01128                                 break;
01129                         case SWITCH_STATUS_NOT_INITALIZED:
01130                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
01131                                 write_frame = NULL;
01132                                 goto error;
01133                         default:
01134                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
01135                                                                   session->read_codec->codec_interface->interface_name);
01136                                 write_frame = NULL;
01137                                 goto error;
01138                         }
01139                         if (flag & SFF_CNG) {
01140                                 switch_set_flag(write_frame, SFF_CNG);
01141                         }
01142 
01143                         status = perform_write(session, write_frame, flags, stream_id);
01144                         goto error;
01145                 } else {
01146                         if (!session->raw_write_buffer) {
01147                                 switch_size_t bytes_per_packet = session->write_impl.decoded_bytes_per_packet;
01148                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
01149                                                                   "Engaging Write Buffer at %u bytes to accommodate %u->%u\n",
01150                                                                   (uint32_t) bytes_per_packet, write_frame->datalen, session->write_impl.decoded_bytes_per_packet);
01151                                 if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer,
01152                                                                                                                    bytes_per_packet * SWITCH_BUFFER_BLOCK_FRAMES,
01153                                                                                                                    bytes_per_packet * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) {
01154                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer Failed!\n");
01155                                         goto error;
01156                                 }
01157 
01158                                 /* Need to retrain the recording data */
01159                                 switch_core_media_bug_flush_all(session);
01160                         }
01161 
01162                         if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) {
01163                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen);
01164                                 status = SWITCH_STATUS_MEMERR;
01165                                 goto error;
01166                         }
01167 
01168                         status = SWITCH_STATUS_SUCCESS;
01169 
01170                         while (switch_buffer_inuse(session->raw_write_buffer) >= session->write_impl.decoded_bytes_per_packet) {
01171                                 int rate;
01172 
01173                                 if (switch_channel_down(session->channel) || !session->raw_write_buffer) {
01174                                         goto error;
01175                                 }
01176                                 if ((session->raw_write_frame.datalen = (uint32_t)
01177                                          switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, session->write_impl.decoded_bytes_per_packet)) == 0) {
01178                                         goto error;
01179                                 }
01180 
01181                                 enc_frame = &session->raw_write_frame;
01182                                 session->raw_write_frame.rate = session->write_impl.actual_samples_per_second;
01183                                 session->enc_write_frame.datalen = session->enc_write_frame.buflen;
01184                                 session->enc_write_frame.timestamp = 0;
01185 
01186 
01187                                 if (frame->codec && frame->codec->implementation && switch_core_codec_ready(frame->codec)) {
01188                                         rate = frame->codec->implementation->actual_samples_per_second;
01189                                 } else {
01190                                         rate = session->write_impl.actual_samples_per_second;
01191                                 }
01192 
01193                                 status = switch_core_codec_encode(session->write_codec,
01194                                                                                                   frame->codec,
01195                                                                                                   enc_frame->data,
01196                                                                                                   enc_frame->datalen,
01197                                                                                                   rate,
01198                                                                                                   session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
01199 
01200 
01201                                 switch (status) {
01202                                 case SWITCH_STATUS_RESAMPLE:
01203                                         resample++;
01204                                         session->enc_write_frame.codec = session->write_codec;
01205                                         session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
01206                                         session->enc_write_frame.m = frame->m;
01207                                         session->enc_write_frame.ssrc = frame->ssrc;
01208                                         session->enc_write_frame.payload = session->write_impl.ianacode;
01209                                         write_frame = &session->enc_write_frame;
01210                                         if (!session->write_resampler) {
01211                                                 switch_mutex_lock(session->resample_mutex);
01212                                                 if (!session->write_resampler) {
01213                                                         status = switch_resample_create(&session->write_resampler,
01214                                                                                                                         frame->codec->implementation->actual_samples_per_second,
01215                                                                                                                         session->write_impl.actual_samples_per_second,
01216                                                                                                                         session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1);
01217                                                 }
01218                                                 switch_mutex_unlock(session->resample_mutex);
01219 
01220 
01221 
01222                                                 if (status != SWITCH_STATUS_SUCCESS) {
01223                                                         goto done;
01224                                                 }
01225                                         }
01226                                         break;
01227                                 case SWITCH_STATUS_SUCCESS:
01228                                         session->enc_write_frame.codec = session->write_codec;
01229                                         session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
01230                                         session->enc_write_frame.m = frame->m;
01231                                         session->enc_write_frame.ssrc = frame->ssrc;
01232                                         session->enc_write_frame.payload = session->write_impl.ianacode;
01233                                         session->enc_write_frame.flags = 0;
01234                                         write_frame = &session->enc_write_frame;
01235                                         break;
01236                                 case SWITCH_STATUS_NOOP:
01237                                         if (session->write_resampler) {
01238                                                 switch_mutex_lock(session->resample_mutex);
01239                                                 if (session->write_resampler) {
01240                                                         switch_resample_destroy(&session->write_resampler);
01241                                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
01242                                                 }
01243                                                 switch_mutex_unlock(session->resample_mutex);
01244                                         }
01245                                         enc_frame->codec = session->write_codec;
01246                                         enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
01247                                         enc_frame->m = frame->m;
01248                                         enc_frame->ssrc = frame->ssrc;
01249                                         enc_frame->payload = enc_frame->codec->implementation->ianacode;
01250                                         write_frame = enc_frame;
01251                                         status = SWITCH_STATUS_SUCCESS;
01252                                         break;
01253                                 case SWITCH_STATUS_NOT_INITALIZED:
01254                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
01255                                         write_frame = NULL;
01256                                         goto error;
01257                                 default:
01258                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n",
01259                                                                           session->read_codec->codec_interface->interface_name, status);
01260                                         write_frame = NULL;
01261                                         goto error;
01262                                 }
01263 
01264                                 if (!did_write_resample && session->read_resampler) {
01265                                         short *data = write_frame->data;
01266                                         switch_mutex_lock(session->resample_mutex);
01267                                         if (session->read_resampler) {
01268                                                 switch_resample_process(session->read_resampler, data, write_frame->datalen / 2);
01269                                                 memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2);
01270                                                 write_frame->samples = session->read_resampler->to_len;
01271                                                 write_frame->datalen = session->read_resampler->to_len * 2;
01272                                                 write_frame->rate = session->read_resampler->to_rate;
01273                                         }
01274                                         switch_mutex_unlock(session->resample_mutex);
01275 
01276                                 }
01277 
01278                                 if (flag & SFF_CNG) {
01279                                         switch_set_flag(write_frame, SFF_CNG);
01280                                 }
01281 
01282                                 if (ptime_mismatch || resample) {
01283                                         write_frame->timestamp = 0;
01284                                 }
01285 
01286                                 if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
01287                                         break;
01288                                 }
01289 
01290                         }
01291 
01292                         goto error;
01293                 }
01294         }
01295 
01296 
01297 
01298 
01299 
01300   done:
01301 
01302         if (ptime_mismatch || resample) {
01303                 write_frame->timestamp = 0;
01304         }
01305 
01306         if (do_write) {
01307                 status = perform_write(session, write_frame, flags, stream_id);
01308         }
01309 
01310   error:
01311 
01312         switch_mutex_unlock(session->write_codec->mutex);
01313         switch_mutex_unlock(frame->codec->mutex);
01314         switch_mutex_unlock(session->codec_write_mutex);
01315 
01316         return status;
01317 }

switch_status_t switch_core_session_write_video_frame ( switch_core_session_t session,
switch_frame_t frame,
switch_io_flag_t  flags,
int  stream_id 
)

Definition at line 38 of file switch_core_io.c.

References switch_io_event_hook_video_write_frame::next, switch_channel_down, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_io_event_hook_video_write_frame::video_write_frame.

00040 {
00041         switch_io_event_hook_video_write_frame_t *ptr;
00042         switch_status_t status = SWITCH_STATUS_FALSE;
00043 
00044         if (switch_channel_down(session->channel)) {
00045                 return SWITCH_STATUS_FALSE;
00046         }
00047 
00048         if (session->endpoint_interface->io_routines->write_video_frame) {
00049                 if ((status = session->endpoint_interface->io_routines->write_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
00050                         for (ptr = session->event_hooks.video_write_frame; ptr; ptr = ptr->next) {
00051                                 if ((status = ptr->video_write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
00052                                         break;
00053                                 }
00054                         }
00055                 }
00056         }
00057         return status;
00058 }


Variable Documentation

char* SIG_NAMES[] [static]

Initial value:

 {
        "NONE",
        "KILL",
        "XFER",
        "BREAK",
        NULL
}

Definition at line 1319 of file switch_core_io.c.


Generated on Sun May 20 04:00:09 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7