#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.
| 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 }
char* SIG_NAMES[] [static] |
Initial value:
{
"NONE",
"KILL",
"XFER",
"BREAK",
NULL
}
Definition at line 1319 of file switch_core_io.c.
1.4.7