Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

switch_core_io.c File Reference


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)
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)


Function Documentation

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
 

00923 {
00924         switch_io_event_hook_kill_channel_t *ptr;
00925         switch_status_t status = SWITCH_STATUS_FALSE;
00926 
00927         switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG, "Kill %s [%s]\n", switch_channel_get_name(session->channel),
00928                                           SIG_NAMES[sig]);
00929 
00930         if (session->endpoint_interface->io_routines->kill_channel) {
00931                 if ((status = session->endpoint_interface->io_routines->kill_channel(session, sig)) == SWITCH_STATUS_SUCCESS) {
00932                         for (ptr = session->event_hooks.kill_channel; ptr; ptr = ptr->next) {
00933                                 if ((status = ptr->kill_channel(session, sig)) != SWITCH_STATUS_SUCCESS) {
00934                                         break;
00935                                 }
00936                         }
00937                 }
00938         }
00939         return status;
00940 }

Here is the call graph for this function:

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
 

00102 {
00103         switch_io_event_hook_read_frame_t *ptr;
00104         switch_status_t status;
00105         int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0;
00106         unsigned int flag = 0;
00107 
00108         switch_assert(session != NULL);
00109 
00110 top:
00111 
00112         if (switch_channel_get_state(session->channel) >= CS_HANGUP) {
00113                 *frame = NULL;
00114                 return SWITCH_STATUS_FALSE;
00115         }
00116 
00117 
00118         status = SWITCH_STATUS_FALSE;
00119         need_codec = perfect = 0;
00120 
00121         *frame = NULL;
00122 
00123         if (switch_channel_test_flag(session->channel, CF_HOLD)) {
00124                 status = SWITCH_STATUS_BREAK;
00125                 goto even_more_done;
00126         }
00127 
00128         if (session->endpoint_interface->io_routines->read_frame) {
00129                 if ((status =
00130                          session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
00131                         for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) {
00132                                 if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
00133                                         break;
00134                                 }
00135                         }
00136                 }
00137         }
00138 
00139         if (status != SWITCH_STATUS_SUCCESS) {
00140                 goto done;
00141         }
00142 
00143         if (!(*frame)) {
00144                 goto done;
00145         }
00146 
00147         switch_assert(*frame != NULL);
00148 
00149         if (switch_test_flag(*frame, SFF_PROXY_PACKET)) {
00150                 /* Fast PASS! */
00151                 status = SWITCH_STATUS_SUCCESS;
00152                 goto done;
00153         } 
00154 
00155         if (switch_test_flag(*frame, SFF_CNG)) {
00156                 status = SWITCH_STATUS_SUCCESS;
00157                 if (!session->bugs) {
00158                         goto done;
00159                 }
00160                 is_cng = 1;
00161         } 
00162 
00163         switch_assert((*frame)->codec != NULL);
00164 
00165         if (!(session->read_codec && session->read_codec->implementation)) {
00166                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
00167                 abort();
00168                 return SWITCH_STATUS_FALSE;
00169         }
00170 
00171         if (((*frame)->codec && session->read_codec->implementation != (*frame)->codec->implementation)) {
00172                 need_codec = TRUE;
00173         }
00174 
00175         if (session->read_codec && !(*frame)->codec) {
00176                 need_codec = TRUE;
00177         }
00178 
00179         if (!session->read_codec && (*frame)->codec) {
00180                 status = SWITCH_STATUS_FALSE;
00181                 goto done;
00182         }
00183 
00184         if ((*frame)->codec->implementation->actual_samples_per_second != session->read_codec->implementation->actual_samples_per_second) {
00185                 do_resample = 1;
00186         }
00187 
00188         if (session->bugs && !need_codec) {
00189                 do_bugs = 1;
00190                 need_codec = 1;
00191         }
00192 
00193         if (status == SWITCH_STATUS_SUCCESS && need_codec) {
00194                 switch_frame_t *enc_frame, *read_frame = *frame;
00195 
00196                 if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
00197                         switch_core_session_message_t msg = { 0 };
00198                         
00199                         msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;
00200                         switch_core_session_receive_message(session, &msg);
00201                         switch_set_flag(session, SSF_WARN_TRANSCODE);
00202                 }
00203                 
00204                 if (read_frame->codec || is_cng) {
00205                         session->raw_read_frame.datalen = session->raw_read_frame.buflen;
00206                         
00207                         if (is_cng) {
00208                                 memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->bytes_per_frame);
00209                                 session->raw_read_frame.datalen = read_frame->codec->implementation->bytes_per_frame;
00210                                 session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
00211                                 read_frame = &session->raw_read_frame;
00212                                 status = SWITCH_STATUS_SUCCESS;
00213                         } else {
00214                                 switch_codec_t *use_codec = read_frame->codec;
00215                                 if (do_bugs) {
00216                                         if (!session->bug_codec.implementation) {
00217                                                 switch_core_codec_copy(read_frame->codec, &session->bug_codec, switch_core_session_get_pool(session));
00218                                         }
00219                                         use_codec = &session->bug_codec;
00220                                 }
00221 
00222                                 status = switch_core_codec_decode(use_codec,
00223                                                                                                   session->read_codec,
00224                                                                                                   read_frame->data,
00225                                                                                                   read_frame->datalen,
00226                                                                                                   session->read_codec->implementation->actual_samples_per_second,
00227                                                                                                   session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &flag);
00228                         }
00229 
00230                         if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) {
00231                                 status = SWITCH_STATUS_RESAMPLE;
00232                         }
00233 
00234                         switch (status) {
00235                         case SWITCH_STATUS_RESAMPLE:
00236                                 if (!session->read_resampler) {
00237                                         switch_mutex_lock(session->resample_mutex);
00238                                         status = switch_resample_create(&session->read_resampler,
00239                                                                                                         read_frame->codec->implementation->actual_samples_per_second,
00240                                                                                                         read_frame->codec->implementation->bytes_per_frame,
00241                                                                                                         session->read_codec->implementation->actual_samples_per_second,
00242                                                                                                         session->read_codec->implementation->bytes_per_frame, session->pool);
00243                                         switch_mutex_unlock(session->resample_mutex);
00244                                         
00245                                         if (status != SWITCH_STATUS_SUCCESS) {
00246                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
00247                                                 status = SWITCH_STATUS_FALSE;
00248                                                 goto done;
00249                                         }
00250                                 }
00251                         case SWITCH_STATUS_SUCCESS:
00252                                 session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
00253                                 session->raw_read_frame.rate = read_frame->rate;
00254                                 session->raw_read_frame.timestamp = read_frame->timestamp;
00255                                 session->raw_read_frame.ssrc = read_frame->ssrc;
00256                                 session->raw_read_frame.seq = read_frame->seq;
00257                                 session->raw_read_frame.m = read_frame->m;
00258                                 session->raw_read_frame.payload = read_frame->payload;
00259                                 read_frame = &session->raw_read_frame;
00260                                 break;
00261                         case SWITCH_STATUS_NOOP:
00262                                 if (session->read_resampler) {
00263                                         switch_mutex_lock(session->resample_mutex);
00264                                         switch_resample_destroy(&session->read_resampler);
00265                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
00266                                         switch_mutex_unlock(session->resample_mutex);                                   
00267                                 }
00268 
00269                                 status = SWITCH_STATUS_SUCCESS;
00270                                 break;
00271                         case SWITCH_STATUS_BREAK:
00272                                 memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->bytes_per_frame);
00273                                 session->raw_read_frame.datalen = read_frame->codec->implementation->bytes_per_frame;
00274                                 session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
00275                                 session->raw_read_frame.timestamp = read_frame->timestamp;
00276                                 session->raw_read_frame.rate = read_frame->rate;
00277                                 session->raw_read_frame.ssrc = read_frame->ssrc;
00278                                 session->raw_read_frame.seq = read_frame->seq;
00279                                 session->raw_read_frame.m = read_frame->m;
00280                                 session->raw_read_frame.payload = read_frame->payload;
00281                                 read_frame = &session->raw_read_frame;
00282                                 status = SWITCH_STATUS_SUCCESS;
00283                                 break;
00284                         default:
00285                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s decoder error!\n", session->read_codec->codec_interface->interface_name);
00286                                 goto done;
00287                         }
00288                 }
00289 
00290                 if (session->bugs) {
00291                         switch_media_bug_t *bp, *dp, *last = NULL;
00292                         switch_bool_t ok = SWITCH_TRUE;
00293                         switch_thread_rwlock_rdlock(session->bug_rwlock);
00294                         for (bp = session->bugs; bp; bp = bp->next) {
00295                                 if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) {
00296                                         switch_mutex_lock(bp->read_mutex);
00297                                         switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen);
00298                                         if (bp->callback) {
00299                                                 if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ) == SWITCH_FALSE || (bp->stop_time && bp->stop_time <= switch_timestamp(NULL))) {
00300                                                         ok = SWITCH_FALSE;
00301                                                 }
00302                                         }
00303                                         switch_mutex_unlock(bp->read_mutex);
00304                                 } 
00305 
00306                                 if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
00307                                         do_bugs = 0;
00308                                         if (bp->callback) {
00309                                                 bp->read_replace_frame_in = read_frame;
00310                                                 bp->read_replace_frame_out = read_frame;
00311                                                 if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) {
00312                                                         read_frame = bp->read_replace_frame_out;
00313                                                 }
00314                                         }
00315                                 }
00316 
00317                                 if (ok == SWITCH_FALSE) {
00318                                         bp->ready = 0;
00319                                         if (last) {
00320                                                 last->next = bp->next;
00321                                         } else {
00322                                                 session->bugs = bp->next;
00323                                         }
00324                                         dp = bp;
00325                                         bp = last;
00326                                         switch_core_media_bug_close(&dp);
00327                                         if (!bp) {
00328                                                 break;
00329                                         }
00330                                         continue;
00331                                 }
00332                                 last = bp;
00333                         }
00334                         switch_thread_rwlock_unlock(session->bug_rwlock);
00335                 }
00336 
00337                 if (do_bugs) {
00338                         goto done;
00339                 }
00340 
00341                 if (session->read_codec) {
00342             if (session->read_resampler) {
00343                 short *data = read_frame->data;
00344                 switch_mutex_lock(session->resample_mutex);
00345                 
00346                 session->read_resampler->from_len = switch_short_to_float(data, session->read_resampler->from, (int) read_frame->datalen / 2);
00347                 session->read_resampler->to_len =
00348                     switch_resample_process(session->read_resampler, session->read_resampler->from,
00349                                             session->read_resampler->from_len, session->read_resampler->to, session->read_resampler->to_size, 0);
00350                 switch_float_to_short(session->read_resampler->to, data, read_frame->datalen);
00351                 read_frame->samples = session->read_resampler->to_len;
00352                 read_frame->datalen = session->read_resampler->to_len * 2;
00353                 read_frame->rate = session->read_resampler->to_rate;
00354                 switch_mutex_unlock(session->resample_mutex);
00355                 
00356             }
00357 
00358                         if ((*frame)->datalen == session->read_codec->implementation->bytes_per_frame) {
00359                                 perfect = TRUE;
00360                         } else {
00361                                 if (!session->raw_read_buffer) {
00362                                         switch_size_t bytes = session->read_codec->implementation->bytes_per_frame;
00363                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes\n", (uint32_t) bytes);
00364                                         switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0);
00365                                 }
00366                                 if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) {
00367                                         status = SWITCH_STATUS_MEMERR;
00368                                         goto done;
00369                                 }
00370                         }
00371                         
00372 
00373                         if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_codec->implementation->bytes_per_frame) {
00374                                 if (perfect) {
00375                                         enc_frame = *frame;
00376                                         session->raw_read_frame.rate = (*frame)->rate;
00377                                 } else {
00378                                         session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer,
00379                                                                                                                                                                         session->raw_read_frame.data,
00380                                                                                                                                                                         session->read_codec->implementation->bytes_per_frame);
00381 
00382                                         session->raw_read_frame.rate = session->read_codec->implementation->actual_samples_per_second;
00383                                         enc_frame = &session->raw_read_frame;
00384                                 }
00385                                 session->enc_read_frame.datalen = session->enc_read_frame.buflen;
00386 
00387                                 switch_assert(session->read_codec != NULL);
00388                                 switch_assert(enc_frame != NULL);
00389                                 switch_assert(enc_frame->data != NULL);
00390 
00391                                 status = switch_core_codec_encode(session->read_codec,
00392                                                                                                   enc_frame->codec,
00393                                                                                                   enc_frame->data,
00394                                                                                                   enc_frame->datalen,
00395                                                                                                   session->read_codec->implementation->actual_samples_per_second,
00396                                                                                                   session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag);
00397 
00398                                 switch (status) {
00399                                 case SWITCH_STATUS_RESAMPLE:
00400                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "fixme 1\n");
00401                                 case SWITCH_STATUS_SUCCESS:
00402                                         session->enc_read_frame.samples = session->read_codec->implementation->bytes_per_frame / sizeof(int16_t);
00403                                         if (perfect) {
00404                                                 session->enc_read_frame.timestamp = read_frame->timestamp;
00405                                                 session->enc_read_frame.rate = read_frame->rate;
00406                                                 session->enc_read_frame.ssrc = read_frame->ssrc;
00407                                                 session->enc_read_frame.seq = read_frame->seq;
00408                                                 session->enc_read_frame.m = read_frame->m;
00409                                                 session->enc_read_frame.payload = session->read_codec->implementation->ianacode;
00410                                         }
00411                                         *frame = &session->enc_read_frame;
00412                                         break;
00413                                 case SWITCH_STATUS_NOOP:
00414                                         session->raw_read_frame.samples = enc_frame->codec->implementation->samples_per_frame;
00415                                         session->raw_read_frame.timestamp = read_frame->timestamp;
00416                                         session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode;
00417                                         session->raw_read_frame.m = read_frame->m;
00418                                         session->raw_read_frame.ssrc = read_frame->ssrc;
00419                                         session->raw_read_frame.seq = read_frame->seq;
00420                                         *frame = &session->raw_read_frame;
00421                                         status = SWITCH_STATUS_SUCCESS;
00422                                         break;
00423                                 default:
00424                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
00425                                                                           session->read_codec->codec_interface->interface_name);
00426                                         *frame = NULL;
00427                                         status = SWITCH_STATUS_GENERR;
00428                                         break;
00429                                 }
00430                         } else {
00431                                 goto top;
00432                         }
00433                 }
00434         }
00435 
00436   done:
00437         if (!(*frame)) {
00438                 status = SWITCH_STATUS_FALSE;
00439         } else {
00440                 if (flag & SFF_CNG) {
00441                         switch_set_flag((*frame), SFF_CNG);
00442                 }
00443                 if (session->bugs) {
00444                         switch_media_bug_t *bp, *dp, *last = NULL;
00445                         switch_bool_t ok = SWITCH_TRUE;
00446                         switch_thread_rwlock_rdlock(session->bug_rwlock);
00447                         for (bp = session->bugs; bp; bp = bp->next) {
00448                                 if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) {
00449                                         switch_mutex_lock(bp->read_mutex);
00450                                         if (bp->callback) {
00451                                                 if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_PING) == SWITCH_FALSE || (bp->stop_time && bp->stop_time <= switch_timestamp(NULL))) {
00452                                                         ok = SWITCH_FALSE;
00453                                                 }
00454                                         }
00455                                         switch_mutex_unlock(bp->read_mutex);
00456                                 }
00457 
00458                                 if (ok == SWITCH_FALSE) {
00459                                         bp->ready = 0;
00460                                         if (last) {
00461                                                 last->next = bp->next;
00462                                         } else {
00463                                                 session->bugs = bp->next;
00464                                         }
00465                                         dp = bp;
00466                                         bp = last;
00467                                         switch_core_media_bug_close(&dp);
00468                                         if (!bp) {
00469                                                 break;
00470                                         }
00471                                         continue;
00472                                 }
00473                                 last = bp;
00474                         }
00475                         switch_thread_rwlock_unlock(session->bug_rwlock);
00476                 }
00477         }
00478 
00479  even_more_done:
00480 
00481         if (!*frame) {
00482                 *frame = &runtime.dummy_cng_frame;
00483         }
00484 
00485         return status;
00486 }

Here is the call graph for this function:

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
 

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

Here is the call graph for this function:

switch_status_t switch_core_session_recv_dtmf switch_core_session_t session,
const switch_dtmf_t dtmf
 

00943 {
00944         switch_io_event_hook_recv_dtmf_t *ptr;  
00945         switch_status_t status;
00946         switch_dtmf_t new_dtmf;
00947         
00948         if (switch_channel_get_state(session->channel) >= CS_HANGUP) {
00949                 return SWITCH_STATUS_FALSE;
00950         }
00951 
00952         switch_assert(dtmf);
00953 
00954         new_dtmf = *dtmf;
00955 
00956         if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
00957                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s EXECSSIVE DTMF DIGIT [%c] LEN [%d]\n", 
00958                                                   switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
00959                 new_dtmf.duration = switch_core_max_dtmf_duration(0);
00960         } else if (!new_dtmf.duration) {
00961                 new_dtmf.duration = switch_core_default_dtmf_duration(0);
00962         }
00963 
00964         for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) {
00965                 if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) {
00966                         return status;
00967                 }
00968         }
00969         return SWITCH_STATUS_SUCCESS;
00970 }

Here is the call graph for this function:

switch_status_t switch_core_session_send_dtmf switch_core_session_t session,
const switch_dtmf_t dtmf
 

00973 {
00974         switch_io_event_hook_send_dtmf_t *ptr;
00975         switch_status_t status = SWITCH_STATUS_FALSE;
00976         switch_dtmf_t new_dtmf;
00977         
00978         if (switch_channel_get_state(session->channel) >= CS_HANGUP) {
00979                 return SWITCH_STATUS_FALSE;
00980         }
00981 
00982         switch_assert(dtmf);
00983 
00984         new_dtmf = *dtmf;
00985 
00986         if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
00987                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s EXECSSIVE DTMF DIGIT [%c] LEN [%d]\n", 
00988                                                   switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
00989                 new_dtmf.duration = switch_core_max_dtmf_duration(0);
00990         } else if (!new_dtmf.duration) {
00991                 new_dtmf.duration = switch_core_default_dtmf_duration(0);
00992         }
00993 
00994 
00995         for (ptr = session->event_hooks.send_dtmf; ptr; ptr = ptr->next) {
00996                 if ((status = ptr->send_dtmf(session, dtmf, SWITCH_DTMF_SEND)) != SWITCH_STATUS_SUCCESS) {
00997                         return SWITCH_STATUS_SUCCESS;
00998                 }
00999         }
01000         
01001         if (session->endpoint_interface->io_routines->send_dtmf) {
01002                 if (dtmf->digit == 'w') {
01003                         switch_yield(500000);
01004                 } else if (dtmf->digit == 'W') {
01005                         switch_yield(1000000);
01006                 } else {
01007                         status = session->endpoint_interface->io_routines->send_dtmf(session, &new_dtmf);
01008                 }
01009         }
01010         return status;
01011 }

Here is the call graph for this function:

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
 

00508 {
00509 
00510         switch_status_t status = SWITCH_STATUS_FALSE;
00511         switch_frame_t *enc_frame = NULL, *write_frame = frame;
00512         unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0;
00513 
00514         switch_assert(session != NULL);
00515         switch_assert(frame != NULL);
00516 
00517         if (switch_channel_get_state(session->channel) >= CS_HANGUP) {
00518                 return SWITCH_STATUS_FALSE;
00519         }
00520 
00521         if (!(session->write_codec && session->write_codec->implementation)) {
00522                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s has no write codec.\n", switch_channel_get_name(session->channel));
00523                 return SWITCH_STATUS_FALSE;
00524         }
00525 
00526         if (switch_channel_test_flag(session->channel, CF_HOLD)) {
00527                 return SWITCH_STATUS_SUCCESS;
00528         }
00529 
00530         if (switch_test_flag(frame, SFF_PROXY_PACKET)) {
00531                 /* Fast PASS! */
00532                 return perform_write(session, frame, flag, stream_id);
00533         }
00534 
00535         if (switch_test_flag(frame, SFF_CNG)) {
00536                 if (switch_channel_test_flag(session->channel, CF_ACCEPT_CNG)) {
00537                         return perform_write(session, frame, flag, stream_id);
00538                 }
00539                 return SWITCH_STATUS_SUCCESS;
00540         }
00541 
00542         switch_assert(frame->codec != NULL);
00543 
00544         if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) {
00545                 need_codec = TRUE;
00546                 if (session->write_codec->implementation->codec_id == frame->codec->implementation->codec_id) {
00547                         ptime_mismatch = TRUE;
00548                 }
00549         }
00550 
00551         if (session->write_codec && !frame->codec) {
00552                 need_codec = TRUE;
00553         }
00554 
00555         if (!session->write_codec && frame->codec) {
00556                 return SWITCH_STATUS_FALSE;
00557         }
00558 
00559         if (session->bugs && !need_codec) {
00560                 do_bugs = TRUE;
00561                 need_codec = TRUE;
00562         }
00563 
00564         if (frame->codec->implementation->actual_samples_per_second != session->write_codec->implementation->actual_samples_per_second) {
00565                 need_codec = TRUE;
00566                 do_resample = TRUE;
00567         }
00568 
00569         if (need_codec) {
00570                 if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
00571                         switch_core_session_message_t msg = { 0 };
00572                         
00573                         msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;
00574                         switch_core_session_receive_message(session, &msg);
00575                         switch_set_flag(session, SSF_WARN_TRANSCODE);
00576                 }
00577 
00578                 if (frame->codec) {
00579                         session->raw_write_frame.datalen = session->raw_write_frame.buflen;
00580                         status = switch_core_codec_decode(frame->codec,
00581                                                                                           session->write_codec,
00582                                                                                           frame->data,
00583                                                                                           frame->datalen,
00584                                                                                           session->write_codec->implementation->actual_samples_per_second,
00585                                                                                           session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &flag);
00586 
00587 
00588 
00589 
00590                         if (do_resample && status == SWITCH_STATUS_SUCCESS) {
00591                                 status = SWITCH_STATUS_RESAMPLE;
00592                         }
00593 
00594                         switch (status) {
00595                         case SWITCH_STATUS_RESAMPLE:
00596                                 write_frame = &session->raw_write_frame;
00597                                 if (!session->write_resampler) {
00598                                         switch_mutex_lock(session->resample_mutex);
00599                                         status = switch_resample_create(&session->write_resampler,
00600                                                                                                         frame->codec->implementation->actual_samples_per_second,
00601                                                                                                         frame->codec->implementation->bytes_per_frame,
00602                                                                                                         session->write_codec->implementation->actual_samples_per_second,
00603                                                                                                         session->write_codec->implementation->bytes_per_frame, session->pool);
00604                                         switch_mutex_unlock(session->resample_mutex);
00605                                         if (status != SWITCH_STATUS_SUCCESS) {
00606                                                 goto done;
00607                                         }
00608                                 }
00609                                 break;
00610                         case SWITCH_STATUS_SUCCESS:
00611                                 session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t);
00612                                 session->raw_write_frame.timestamp = frame->timestamp;
00613                                 session->raw_write_frame.rate = frame->rate;
00614                                 session->raw_write_frame.m = frame->m;
00615                                 session->raw_write_frame.ssrc = frame->ssrc;
00616                                 session->raw_write_frame.seq = frame->seq;
00617                                 session->raw_write_frame.payload = frame->payload;
00618                                 write_frame = &session->raw_write_frame;
00619                                 break;
00620                         case SWITCH_STATUS_BREAK:
00621                                 return SWITCH_STATUS_SUCCESS;
00622                         case SWITCH_STATUS_NOOP:
00623                                 if (session->write_resampler) {
00624                                         switch_mutex_lock(session->resample_mutex);
00625                                         switch_resample_destroy(&session->write_resampler);
00626                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
00627                                         switch_mutex_unlock(session->resample_mutex);
00628                                 }
00629                                 write_frame = frame;
00630                                 status = SWITCH_STATUS_SUCCESS;
00631                                 break;
00632                         default:
00633                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s decoder error!\n", frame->codec->codec_interface->interface_name);
00634                                 return status;
00635                         }
00636                 }
00637 
00638                 if (session->write_resampler) {
00639                         short *data = write_frame->data;
00640                         
00641                         switch_mutex_lock(session->resample_mutex);
00642 
00643                         session->write_resampler->from_len = write_frame->datalen / 2;
00644                         switch_short_to_float(data, session->write_resampler->from, session->write_resampler->from_len);
00645 
00646                         session->write_resampler->to_len = (uint32_t)
00647                                 switch_resample_process(session->write_resampler, session->write_resampler->from,
00648                                                                                 session->write_resampler->from_len, session->write_resampler->to, session->write_resampler->to_size, 0);
00649 
00650                         switch_float_to_short(session->write_resampler->to, data, session->write_resampler->to_len);
00651 
00652                         write_frame->samples = session->write_resampler->to_len;
00653                         write_frame->datalen = write_frame->samples * 2;
00654                         write_frame->rate = session->write_resampler->to_rate;
00655                         switch_mutex_unlock(session->resample_mutex);
00656                 }
00657 
00658                 if (session->bugs) {
00659                         switch_media_bug_t *bp, *dp, *last = NULL;
00660 
00661                         switch_thread_rwlock_rdlock(session->bug_rwlock);
00662                         for (bp = session->bugs; bp; bp = bp->next) {
00663                                 switch_bool_t ok = SWITCH_TRUE;
00664                                 if (!bp->ready) {
00665                                         continue;
00666                                 }
00667                                 if (switch_test_flag(bp, SMBF_WRITE_STREAM)) {
00668                                         
00669                                         switch_mutex_lock(bp->write_mutex);
00670                                         switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen);
00671                                         switch_mutex_unlock(bp->write_mutex);
00672                                         if (bp->callback) {
00673                                                 ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
00674                                         }
00675                                 } 
00676 
00677                                 if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
00678                                         do_bugs = 0;
00679                                         if (bp->callback) {
00680                                                 bp->write_replace_frame_in = write_frame;
00681                                                 bp->write_replace_frame_out = write_frame;
00682                                                 if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) {
00683                                                         write_frame = bp->write_replace_frame_out;
00684                                                 }
00685                                         }
00686                                 }
00687 
00688                                 if (bp->stop_time && bp->stop_time <= switch_timestamp(NULL)) {
00689                                         ok = SWITCH_FALSE;
00690                                 }
00691 
00692 
00693                                 if (ok == SWITCH_FALSE) {
00694                                         bp->ready = 0;
00695                                         if (last) {
00696                                                 last->next = bp->next;
00697                                         } else {
00698                                                 session->bugs = bp->next;
00699                                         }
00700                                         dp = bp;
00701                                         bp = last;
00702                                         switch_core_media_bug_close(&dp);
00703                                         if (!bp) {
00704                                                 break;
00705                                         }
00706                                         continue;
00707                                 }
00708                                 last = bp;
00709                         }
00710                         switch_thread_rwlock_unlock(session->bug_rwlock);
00711                 }
00712 
00713                 if (do_bugs) {
00714                         do_write = TRUE;
00715                         write_frame = frame;
00716                         goto done;
00717                 }
00718 
00719                 if (session->write_codec) {
00720                         if (write_frame->datalen == session->write_codec->implementation->bytes_per_frame) {
00721                                 perfect = TRUE;
00722                         } else {
00723                                 if (!session->raw_write_buffer) {
00724                                         switch_size_t bytes = session->write_codec->implementation->bytes_per_frame;
00725                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
00726                                                                           "Engaging Write Buffer at %u bytes to accomodate %u->%u\n",
00727                                                                           (uint32_t) bytes, write_frame->datalen, session->write_codec->implementation->bytes_per_frame);
00728                                         if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer,
00729                                                                                                                            bytes * SWITCH_BUFFER_BLOCK_FRAMES,
00730                                                                                                                            bytes * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) {
00731                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer Failed!\n");
00732                                                 return status;
00733                                         }
00734                                 }
00735 
00736                                 if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) {
00737                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen);
00738                                         return SWITCH_STATUS_MEMERR;
00739                                 }
00740                         }
00741 
00742                         if (perfect) {
00743                                 enc_frame = write_frame;
00744                                 session->enc_write_frame.datalen = session->enc_write_frame.buflen;
00745 
00746                                 status = switch_core_codec_encode(session->write_codec,
00747                                                                                                   frame->codec,
00748                                                                                                   enc_frame->data,
00749                                                                                                   enc_frame->datalen,
00750                                                                                                   session->write_codec->implementation->actual_samples_per_second,
00751                                                                                                   session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
00752 
00753                                 switch (status) {
00754                                 case SWITCH_STATUS_RESAMPLE:
00755                                         //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "fixme 2\n");
00756                                 case SWITCH_STATUS_SUCCESS:
00757                                         session->enc_write_frame.codec = session->write_codec;
00758                                         session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
00759                                         session->enc_write_frame.timestamp = frame->timestamp;
00760                                         session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
00761                                         session->enc_write_frame.m = frame->m;
00762                                         session->enc_write_frame.ssrc = frame->ssrc;
00763                                         session->enc_write_frame.seq = frame->seq;
00764                                         write_frame = &session->enc_write_frame;
00765                                         break;
00766                                 case SWITCH_STATUS_NOOP:
00767                                         enc_frame->codec = session->write_codec;
00768                                         enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
00769                                         enc_frame->timestamp = frame->timestamp;
00770                                         enc_frame->m = frame->m;
00771                                         enc_frame->seq = frame->seq;
00772                                         enc_frame->ssrc = frame->ssrc;
00773                                         enc_frame->payload = enc_frame->codec->implementation->ianacode;
00774                                         write_frame = enc_frame;
00775                                         status = SWITCH_STATUS_SUCCESS;
00776                                         break;
00777                                 default:
00778                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
00779                                                                           session->read_codec->codec_interface->interface_name);
00780                                         write_frame = NULL;
00781                                         return status;
00782                                 }
00783                                 if (flag & SFF_CNG) {
00784                                         switch_set_flag(write_frame, SFF_CNG);
00785                                 }
00786                                 status = perform_write(session, write_frame, flags, stream_id);
00787                                 return status;
00788                         } else {
00789                                 switch_size_t used = switch_buffer_inuse(session->raw_write_buffer);
00790                                 uint32_t bytes = session->write_codec->implementation->bytes_per_frame;
00791                                 switch_size_t frames = (used / bytes);
00792 
00793                                 status = SWITCH_STATUS_SUCCESS;
00794                                 if (!frames) {
00795                                         return status;
00796                                 } else {
00797                                         switch_size_t x;
00798                                         for (x = 0; x < frames; x++) {
00799                                                 if ((session->raw_write_frame.datalen = (uint32_t)
00800                                                          switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, bytes)) != 0) {
00801                                                         int rate;
00802                                                         enc_frame = &session->raw_write_frame;
00803                                                         session->raw_write_frame.rate = session->write_codec->implementation->actual_samples_per_second;
00804                                                         session->enc_write_frame.datalen = session->enc_write_frame.buflen;
00805 
00806                                                         if (frame->codec && frame->codec->implementation) {
00807                                                                 rate = frame->codec->implementation->actual_samples_per_second;
00808                                                         } else {
00809                                                                 rate = session->write_codec->implementation->actual_samples_per_second;
00810                                                         } 
00811                                                         
00812                                                         status = switch_core_codec_encode(session->write_codec,
00813