FreeSWITCH API Documentation  1.7.0
Functions | Variables
switch_core_io.c File Reference
#include <switch.h>
#include "private/switch_core_pvt.h"
+ Include dependency graph for switch_core_io.c:

Go to the source code of this file.

Functions

void switch_core_gen_encoded_silence (unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len)
 
switch_status_t switch_core_session_read_frame (switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
 
static switch_status_t perform_write (switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
 
switch_status_t switch_core_session_write_frame (switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
 
switch_status_t switch_core_session_perform_kill_channel (switch_core_session_t *session, const char *file, const char *func, int line, switch_signal_t sig)
 
switch_status_t switch_core_session_recv_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf)
 
switch_status_t switch_core_session_send_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf)
 
switch_status_t switch_core_session_send_dtmf_string (switch_core_session_t *session, const char *dtmf_string)
 Send DTMF to a session. More...
 

Variables

static char * SIG_NAMES []
 

Function Documentation

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

Definition at line 948 of file switch_core_io.c.

References switch_core_session::bug_rwlock, switch_core_session::bugs, switch_media_bug::callback, CF_ANSWERED, CF_PAUSE_BUGS, switch_core_session::channel, switch_core_session::endpoint_interface, switch_core_session::event_hooks, switch_frame::flags, switch_endpoint_interface::io_routines, switch_media_bug::native_write_frame, switch_io_event_hook_write_frame::next, switch_media_bug::next, switch_media_bug::ready, SFF_NOT_AUDIO, SMBF_ANSWER_REQ, SMBF_NO_PAUSE, SMBF_PRUNE, SMBF_TAP_NATIVE_WRITE, switch_media_bug::stop_time, SWITCH_ABC_TYPE_TAP_NATIVE_WRITE, switch_channel_test_flag(), switch_core_media_bug_prune(), switch_core_media_bug_test_flag(), switch_epoch_time_now(), SWITCH_FALSE, switch_set_flag, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_rwlock_rdlock(), switch_thread_rwlock_unlock(), SWITCH_TRUE, switch_media_bug::user_data, switch_io_event_hook_write_frame::write_frame, and switch_io_routines::write_frame.

Referenced by switch_core_session_write_frame().

949 {
952 
953 
954  if (session->bugs && !(frame->flags & SFF_NOT_AUDIO)) {
955  switch_media_bug_t *bp;
957  int prune = 0;
958 
960 
961  for (bp = session->bugs; bp; bp = bp->next) {
962  ok = SWITCH_TRUE;
963 
965  continue;
966  }
967 
969  continue;
970  }
971  if (switch_test_flag(bp, SMBF_PRUNE)) {
972  prune++;
973  continue;
974  }
975 
976  if (bp->ready) {
978  if (bp->callback) {
979  bp->native_write_frame = frame;
981  bp->native_write_frame = NULL;
982  }
983  }
984  }
985 
986  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
988  prune++;
989  }
990  }
992 
993  if (prune) {
995  }
996  }
997 
998 
999  if (session->endpoint_interface->io_routines->write_frame) {
1000  if ((status = session->endpoint_interface->io_routines->write_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
1001  for (ptr = session->event_hooks.write_frame; ptr; ptr = ptr->next) {
1002  if ((status = ptr->write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
1003  break;
1004  }
1005  }
1006  }
1007  }
1008 
1009  return status;
1010 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_bool_t
Definition: switch_types.h:405
switch_io_routines_t * io_routines
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_media_bug_callback_t callback
Node in which to store custom write_frame channel callback hooks.
switch_io_event_hooks_t event_hooks
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:227
uint32_t switch_core_media_bug_prune(switch_core_session_t *session)
switch_channel_t * channel
switch_write_frame_hook_t write_frame
switch_frame_flag_t flags
Definition: switch_frame.h:74
switch_media_bug_t * bugs
struct switch_media_bug * next
switch_frame_t * native_write_frame
switch_io_write_frame_t write_frame
switch_status_t
Common return values.
struct switch_io_event_hook_write_frame * next
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
switch_endpoint_interface_t * endpoint_interface
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
void switch_core_gen_encoded_silence ( unsigned char *  data,
const switch_codec_implementation_t read_impl,
switch_size_t  len 
)

Definition at line 39 of file switch_core_io.c.

References memset(), and switch_stristr().

Referenced by record_callback(), and switch_core_session_read_frame().

40 {
41  unsigned char g729_filler[] = {
42  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
43  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
44  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
45  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
46  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
47  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
48  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
49  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
50  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
51  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
52  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
53  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
54  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
55  229, 127, 79, 96, 207, 82, 216, 110, 245, 81
56  };
57 
58 
59  if (read_impl->ianacode == 18 || switch_stristr("g729", read_impl->iananame)) {
60  memcpy(data, g729_filler, len);
61  } else {
62  memset(data, 255, len);
63  }
64 
65 }
const char * switch_stristr(const char *instr, const char *str)
memset(buf, 0, buflen)
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 1658 of file switch_core_io.c.

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

1660 {
1663 
1664  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG10, "Send signal %s [%s]\n",
1665  switch_channel_get_name(session->channel), SIG_NAMES[sig]);
1666 
1667  if (session->endpoint_interface->io_routines->kill_channel) {
1668  if ((status = session->endpoint_interface->io_routines->kill_channel(session, sig)) == SWITCH_STATUS_SUCCESS) {
1669  for (ptr = session->event_hooks.kill_channel; ptr; ptr = ptr->next) {
1670  if ((status = ptr->kill_channel(session, sig)) != SWITCH_STATUS_SUCCESS) {
1671  break;
1672  }
1673  }
1674  }
1675  }
1676  return status;
1677 }
switch_kill_channel_hook_t kill_channel
switch_io_routines_t * io_routines
switch_io_event_hooks_t event_hooks
switch_channel_t * channel
static char * SIG_NAMES[]
struct switch_io_event_hook_kill_channel * next
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
switch_status_t
Common return values.
Node in which to store custom kill channel callback hooks.
switch_io_kill_channel_t kill_channel
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_endpoint_interface_t * endpoint_interface
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
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 67 of file switch_core_io.c.

References switch_codec_implementation::actual_samples_per_second, switch_core_session::bugs, switch_media_bug::callback, CCS_ACTIVE, CCS_UNHELD, CF_ANSWERED, CF_AUDIO_PAUSE, CF_BRIDGED, CF_CNG_PLC, CF_HOLD, CF_JITTERBUFFER_PLC, CF_PAUSE_BUGS, CF_PROXY_MODE, switch_frame::channels, switch_frame::codec, CS_HIBERNATE, switch_codec::cur_frame, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_runtime::dummy_cng_frame, switch_frame::flags, switch_codec_implementation::ianacode, switch_codec_implementation::iananame, if(), switch_codec_implementation::impl_id, switch_codec::implementation, switch_frame::m, memset(), switch_core_session_message::message_id, switch_media_bug::native_read_frame, switch_io_event_hook_read_frame::next, switch_media_bug::next, switch_codec_implementation::number_of_channels, switch_core_session_message::numeric_arg, switch_frame::payload, switch_media_bug::ping_frame, switch_frame::rate, switch_media_bug::raw_read_buffer, switch_media_bug::read_demux_frame, switch_io_event_hook_read_frame::read_frame, switch_media_bug::read_mutex, switch_media_bug::read_replace_frame_in, switch_media_bug::read_replace_frame_out, switch_media_bug::ready, runtime, switch_frame::samples, switch_codec_implementation::samples_per_packet, switch_frame::seq, SFF_CNG, SFF_NOT_AUDIO, SFF_PLC, SFF_PROXY_PACKET, SMBF_ANSWER_REQ, SMBF_BRIDGE_REQ, SMBF_NO_PAUSE, SMBF_PRUNE, SMBF_READ_PING, SMBF_READ_REPLACE, SMBF_READ_STREAM, SMBF_TAP_NATIVE_READ, SSF_MEDIA_BUG_TAP_ONLY, SSF_READ_CODEC_RESET, SSF_READ_TRANSCODE, SSF_WARN_TRANSCODE, SSF_WRITE_CODEC_RESET, switch_frame::ssrc, switch_media_bug::stop_time, SWITCH_ABC_TYPE_READ, SWITCH_ABC_TYPE_READ_PING, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_TAP_NATIVE_READ, 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_INCOMPATIBLE_DESTINATION, switch_channel_down, switch_channel_dtmf_lock(), switch_channel_dtmf_unlock(), switch_channel_event_set_data(), switch_channel_get_callstate(), switch_channel_get_name(), switch_channel_get_partner_uuid(), switch_channel_get_state(), switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_callstate, switch_channel_test_flag(), switch_clear_flag, SWITCH_CODEC_FLAG_HAS_PLC, switch_cond_next(), switch_core_codec_copy(), switch_core_codec_decode(), switch_core_codec_encode(), switch_core_codec_ready(), switch_core_codec_reset(), switch_core_gen_encoded_silence(), switch_core_media_bug_prune(), switch_core_media_bug_test_flag(), switch_core_session_get_channel(), switch_core_session_get_name, switch_core_session_get_partner, switch_core_session_locate, switch_core_session_receive_message, switch_core_session_rwunlock(), switch_epoch_time_now(), switch_event_create, switch_event_fire, SWITCH_EVENT_SESSION_HEARTBEAT, SWITCH_FALSE, switch_ivr_dmachine_ping(), SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_NOTICE, switch_log_printf(), SWITCH_MESSAGE_HEARTBEAT_EVENT, SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY, SWITCH_MESSAGE_RESAMPLE_EVENT, switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), switch_mux_channels(), switch_os_yield(), SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, switch_resample_create, switch_resample_destroy(), switch_resample_process(), SWITCH_RESAMPLE_QUALITY, switch_set_flag, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_INUSE, 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_thread_rwlock_wrlock(), SWITCH_TRUE, switch_unmerge_sln(), switch_yield, switch_frame::timestamp, TRUE, and switch_media_bug::user_data.

69 {
72  int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0, tap_only = 0;
74  unsigned int flag = 0;
75  int i;
76 
77  switch_assert(session != NULL);
78 
79  tap_only = switch_test_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
80 
82 
85  } else {
87  *frame = &runtime.dummy_cng_frame;
88  return SWITCH_STATUS_SUCCESS;
89  }
90 
91  if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) {
93  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n",
96  *frame = &runtime.dummy_cng_frame;
97  return SWITCH_STATUS_SUCCESS;
98  }
99 
101  switch_yield(20000);
102  *frame = &runtime.dummy_cng_frame;
103  // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Media Paused!!!!\n");
104  return SWITCH_STATUS_SUCCESS;
105  }
106 
107  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
109  return SWITCH_STATUS_FALSE;
110  }
111 
113 
114  if (!switch_core_codec_ready(session->read_codec)) {
116  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
118  *frame = &runtime.dummy_cng_frame;
119  return SWITCH_STATUS_FALSE;
120  }
121 
123 
124  top:
125 
126  for(i = 0; i < 2; i++) {
127  if (session->dmachine[i]) {
129  switch_ivr_dmachine_ping(session->dmachine[i], NULL);
131  }
132  }
133 
134  if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) {
135  *frame = NULL;
136  status = SWITCH_STATUS_FALSE;
137  goto even_more_done;
138  }
139 
140 
141  status = SWITCH_STATUS_FALSE;
142  need_codec = perfect = 0;
143 
144  *frame = NULL;
145 
146  if (session->read_codec && !session->track_id && session->track_duration) {
147  if (session->read_frame_count == 0) {
148  switch_event_t *event;
149  switch_core_session_message_t msg = { 0 };
150 
151  session->read_frame_count = (session->read_impl.samples_per_second / session->read_impl.samples_per_packet) * session->track_duration;
152 
154  msg.numeric_arg = session->track_duration;
156 
158  switch_channel_event_set_data(session->channel, event);
159  switch_event_fire(&event);
160  } else {
161  session->read_frame_count--;
162  }
163  }
164 
165 
166  if (switch_channel_test_flag(session->channel, CF_HOLD)) {
168  status = SWITCH_STATUS_BREAK;
169  goto even_more_done;
170  }
171 
172  if (session->endpoint_interface->io_routines->read_frame) {
175  if ((status = session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
176  for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) {
177  if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
178  break;
179  }
180  }
181  }
182 
183  if (status == SWITCH_STATUS_INUSE) {
184  *frame = &runtime.dummy_cng_frame;
185  switch_yield(20000);
186  return SWITCH_STATUS_SUCCESS;
187  }
188 
189  if (!SWITCH_READ_ACCEPTABLE(status) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) {
190  *frame = NULL;
191  return SWITCH_STATUS_FALSE;
192  }
193 
195 
196  if (!switch_core_codec_ready(session->read_codec)) {
198  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
200  *frame = &runtime.dummy_cng_frame;
201  return SWITCH_STATUS_FALSE;
202  }
203 
205  if (!switch_core_codec_ready(session->read_codec)) {
206  *frame = NULL;
207  status = SWITCH_STATUS_FALSE;
208  goto even_more_done;
209  }
210  }
211 
212  if (status != SWITCH_STATUS_SUCCESS) {
213  goto done;
214  }
215 
216  if (!(*frame)) {
217  goto done;
218  }
219 
220  switch_assert(*frame != NULL);
221 
222  if (switch_test_flag(*frame, SFF_PROXY_PACKET)) {
223  /* Fast PASS! */
224  status = SWITCH_STATUS_SUCCESS;
225  goto done;
226  }
227 
228  switch_assert((*frame)->codec != NULL);
229 
230  if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) {
231  status = SWITCH_STATUS_FALSE;
232  goto done;
233  }
234 
235  if (session->bugs && !((*frame)->flags & SFF_CNG) && !((*frame)->flags & SFF_NOT_AUDIO)) {
236  switch_media_bug_t *bp;
238  int prune = 0;
239 
241 
242  for (bp = session->bugs; bp; bp = bp->next) {
243  ok = SWITCH_TRUE;
244 
246  continue;
247  }
248 
250  continue;
251  }
252  if (switch_test_flag(bp, SMBF_PRUNE)) {
253  prune++;
254  continue;
255  }
256 
257  if (bp->ready) {
259  if ((*frame)->codec && (*frame)->codec->implementation &&
260  (*frame)->codec->implementation->encoded_bytes_per_packet &&
261  (*frame)->datalen != (*frame)->codec->implementation->encoded_bytes_per_packet) {
262  switch_set_flag((*frame), SFF_CNG);
263  break;
264  }
265  if (bp->callback) {
266  bp->native_read_frame = *frame;
268  bp->native_read_frame = NULL;
269  }
270  }
271  }
272 
273  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
275  prune++;
276  }
277  }
279 
280  if (prune) {
282  }
283  }
284 
285  codec_impl = *(*frame)->codec->implementation;
286 
287  if (session->read_codec->implementation->impl_id != codec_impl.impl_id) {
288  need_codec = TRUE;
289  tap_only = 0;
290  }
291 
293  do_resample = 1;
294  }
295 
296  if (tap_only) {
297  switch_media_bug_t *bp;
299  int prune = 0;
300 
301  if (session->bugs && switch_test_flag((*frame), SFF_CNG)) {
303  for (bp = session->bugs; bp; bp = bp->next) {
304  ok = SWITCH_TRUE;
305 
307  continue;
308  }
309 
311  continue;
312  }
313  if (switch_test_flag(bp, SMBF_PRUNE)) {
314  prune++;
315  continue;
316  }
317 
318  if (bp->ready && (*frame)->codec && (*frame)->codec->implementation && (*frame)->codec->implementation->encoded_bytes_per_packet) {
320  if (bp->callback) {
321  switch_frame_t tmp_frame = {0};
322  unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
323 
324 
325  tmp_frame.codec = (*frame)->codec;
326  tmp_frame.datalen = (*frame)->codec->implementation->encoded_bytes_per_packet;
327  tmp_frame.samples = (*frame)->codec->implementation->samples_per_packet;
328  tmp_frame.channels = (*frame)->codec->implementation->number_of_channels;
329  tmp_frame.data = data;
330 
331  switch_core_gen_encoded_silence(data, (*frame)->codec->implementation, tmp_frame.datalen);
332 
333  bp->native_read_frame = &tmp_frame;
335  bp->native_read_frame = NULL;
336  }
337  }
338  }
339 
340  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
342  prune++;
343  }
344  }
346 
347  if (prune) {
349  }
350 
351 
352  }
353 
354 
355  goto done;
356  } else if (session->bugs && !need_codec) {
357  do_bugs = 1;
358  need_codec = 1;
359  }
360 
361  if (switch_test_flag(*frame, SFF_CNG)) {
362  if (!session->bugs && !session->plc) {
363  /* Check if other session has bugs */
364  unsigned int other_session_bugs = 0;
365  switch_core_session_t *other_session = NULL;
367  switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
368  if (other_session->bugs && !switch_test_flag(other_session, SSF_MEDIA_BUG_TAP_ONLY)) {
369  other_session_bugs = 1;
370  }
371  switch_core_session_rwunlock(other_session);
372  }
373 
374  /* Don't process CNG frame */
375  if (!other_session_bugs) {
376  status = SWITCH_STATUS_SUCCESS;
377  goto done;
378  }
379  }
380  is_cng = 1;
381  need_codec = 1;
382  } else if (switch_test_flag(*frame, SFF_NOT_AUDIO)) {
383  do_resample = 0;
384  do_bugs = 0;
385  need_codec = 0;
386  }
387 
388  if (switch_test_flag(session, SSF_READ_TRANSCODE) && !need_codec && switch_core_codec_ready(session->read_codec)) {
389  switch_core_session_t *other_session;
392 
393  if (uuid && (other_session = switch_core_session_locate(uuid))) {
394  switch_set_flag(other_session, SSF_READ_CODEC_RESET);
395  switch_set_flag(other_session, SSF_READ_CODEC_RESET);
396  switch_set_flag(other_session, SSF_WRITE_CODEC_RESET);
397  switch_core_session_rwunlock(other_session);
398  }
399  }
400 
401  if (switch_test_flag(session, SSF_READ_CODEC_RESET)) {
404  }
405 
406 
407  if (status == SWITCH_STATUS_SUCCESS && need_codec) {
408  switch_frame_t *enc_frame, *read_frame = *frame;
409 
411 
412  if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
413  switch_core_session_message_t msg = { 0 };
414 
418  }
419 
420  if (read_frame->codec || is_cng) {
421  session->raw_read_frame.datalen = session->raw_read_frame.buflen;
422 
423  if (is_cng) {
424  if (session->plc) {
425  plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2);
426  is_cng = 0;
427  flag &= ~SFF_CNG;
428  } else {
430  }
431 
432  session->raw_read_frame.timestamp = 0;
434  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
436  read_frame = &session->raw_read_frame;
437  status = SWITCH_STATUS_SUCCESS;
438  } else {
439  switch_codec_t *use_codec = read_frame->codec;
440  if (do_bugs) {
442  if (!session->bugs) {
444  goto done;
445  }
446 
447  if (!switch_core_codec_ready(&session->bug_codec) && switch_core_codec_ready(read_frame->codec)) {
448  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting BUG Codec %s:%d\n",
449  read_frame->codec->implementation->iananame, read_frame->codec->implementation->ianacode);
450  switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL, NULL);
451  if (!switch_core_codec_ready(&session->bug_codec)) {
452  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Error setting BUG codec %s!\n",
454  }
455  }
456 
457  if (switch_core_codec_ready(&session->bug_codec)) {
458  use_codec = &session->bug_codec;
459  }
461 
463  if (!session->bugs) {
464  do_bugs = 0;
465  }
467  if (!do_bugs) goto done;
468  }
469 
470  if (!switch_test_flag(read_frame->codec, SWITCH_CODEC_FLAG_HAS_PLC) &&
472  switch_channel_test_flag(session->channel, CF_CNG_PLC)) && !session->plc) {
473  session->plc = plc_init(NULL);
474  }
475 
476  if (!switch_test_flag(read_frame->codec, SWITCH_CODEC_FLAG_HAS_PLC) && session->plc && switch_test_flag(read_frame, SFF_PLC)) {
478  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
480  memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen);
481  status = SWITCH_STATUS_SUCCESS;
482  } else {
483  switch_codec_t *codec = use_codec;
484 
486 
487  if (!switch_core_codec_ready(codec)) {
488  codec = read_frame->codec;
489  }
490 
491  if (!switch_core_codec_ready(codec)) {
493  goto done;
494  }
495 
496  codec->cur_frame = read_frame;
497  session->read_codec->cur_frame = read_frame;
498  status = switch_core_codec_decode(codec,
499  session->read_codec,
500  read_frame->data,
501  read_frame->datalen,
503  session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate,
504  &read_frame->flags);
505 
506  if (status == SWITCH_STATUS_NOT_INITALIZED) {
508  goto done;
509  }
510 
511  session->raw_read_frame.samples = session->raw_read_frame.datalen / 2;
513  codec->cur_frame = NULL;
514  session->read_codec->cur_frame = NULL;
516 
517  }
518 
519  if (status == SWITCH_STATUS_SUCCESS && session->read_impl.number_of_channels == 1) {
520  if (session->plc) {
521  if (switch_test_flag(read_frame, SFF_PLC)) {
522  plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
523  switch_clear_flag(read_frame, SFF_PLC);
524  } else {
525  plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
526  }
527  }
528  }
529 
530 
531  }
532 
533  if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) {
534  status = SWITCH_STATUS_RESAMPLE;
535  }
536 
537  /* mux or demux to match */
538  if (session->raw_read_frame.channels != session->read_impl.number_of_channels) {
539  uint32_t rlen = session->raw_read_frame.datalen / 2 / session->raw_read_frame.channels;
540  switch_mux_channels((int16_t *) session->raw_read_frame.data, rlen, session->raw_read_frame.channels, session->read_impl.number_of_channels);
541  session->raw_read_frame.datalen = rlen * 2 * session->read_impl.number_of_channels;
542  session->raw_read_frame.samples = session->raw_read_frame.datalen / 2;
544  }
545 
546 
547  switch (status) {
549  if (!session->read_resampler) {
551 
552  status = switch_resample_create(&session->read_resampler,
556  session->read_impl.number_of_channels);
557 
559 
560  if (status != SWITCH_STATUS_SUCCESS) {
561  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
562  status = SWITCH_STATUS_FALSE;
563  goto done;
564  } else {
565  switch_core_session_message_t msg = { 0 };
566  msg.numeric_arg = 1;
569 
570  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating read resampler\n");
571  }
572  }
574  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
576  session->raw_read_frame.rate = read_frame->rate;
578  session->raw_read_frame.timestamp = 0;
579  } else {
580  session->raw_read_frame.timestamp = read_frame->timestamp;
581  }
582  session->raw_read_frame.ssrc = read_frame->ssrc;
583  session->raw_read_frame.seq = read_frame->seq;
584  session->raw_read_frame.m = read_frame->m;
585  session->raw_read_frame.payload = read_frame->payload;
586  session->raw_read_frame.flags = 0;
587  if (switch_test_flag(read_frame, SFF_PLC)) {
588  session->raw_read_frame.flags |= SFF_PLC;
589  }
590  read_frame = &session->raw_read_frame;
591  break;
592  case SWITCH_STATUS_NOOP:
593  if (session->read_resampler) {
596  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
598 
599  {
600  switch_core_session_message_t msg = { 0 };
601  msg.numeric_arg = 0;
604  }
605 
606  }
607 
608  status = SWITCH_STATUS_SUCCESS;
609  break;
610  case SWITCH_STATUS_BREAK:
613  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
615  session->raw_read_frame.timestamp = read_frame->timestamp;
616  session->raw_read_frame.rate = read_frame->rate;
617  session->raw_read_frame.ssrc = read_frame->ssrc;
618  session->raw_read_frame.seq = read_frame->seq;
619  session->raw_read_frame.m = read_frame->m;
620  session->raw_read_frame.payload = read_frame->payload;
621  session->raw_read_frame.flags = 0;
622  if (switch_test_flag(read_frame, SFF_PLC)) {
623  session->raw_read_frame.flags |= SFF_PLC;
624  }
625 
626  read_frame = &session->raw_read_frame;
627  status = SWITCH_STATUS_SUCCESS;
628  break;
630  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
631  goto done;
632  default:
633  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error! [%d]\n",
634  session->read_codec->codec_interface->interface_name, status);
635 
636  if (++session->decoder_errors < 10) {
637  status = SWITCH_STATUS_SUCCESS;
638  } else {
639  goto done;
640  }
641  }
642 
643  session->decoder_errors = 0;
644  }
645 
646  if (session->bugs) {
647  switch_media_bug_t *bp;
649  int prune = 0;
651 
652  for (bp = session->bugs; bp; bp = bp->next) {
653  ok = SWITCH_TRUE;
654 
656  continue;
657  }
658 
660  continue;
661  }
662 
664  continue;
665  }
666 
667  if (switch_test_flag(bp, SMBF_PRUNE)) {
668  prune++;
669  continue;
670  }
671 
672  if (ok && switch_test_flag(bp, SMBF_READ_REPLACE)) {
673  do_bugs = 0;
674  if (bp->callback) {
675  bp->read_replace_frame_in = read_frame;
676  bp->read_replace_frame_out = read_frame;
677  bp->read_demux_frame = NULL;
678  if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) {
679  read_frame = bp->read_replace_frame_out;
680  }
681  }
682  }
683 
684  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
686  prune++;
687  }
688 
689 
690  }
692  if (prune) {
694  }
695  }
696 
697  if (session->bugs) {
698  switch_media_bug_t *bp;
700  int prune = 0;
702 
703  for (bp = session->bugs; bp; bp = bp->next) {
704  ok = SWITCH_TRUE;
705 
707  continue;
708  }
709 
711  continue;
712  }
713 
715  continue;
716  }
717 
718  if (switch_test_flag(bp, SMBF_PRUNE)) {
719  prune++;
720  continue;
721  }
722 
723  if (ok && bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) {
725  if (bp->read_demux_frame) {
726  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
727  int bytes = read_frame->datalen;
728  uint32_t datalen = 0;
729  uint32_t samples = bytes / 2 / bp->read_demux_frame->channels;
730 
731  memcpy(data, read_frame->data, read_frame->datalen);
732  datalen = switch_unmerge_sln((int16_t *)data, samples,
733  bp->read_demux_frame->data, samples,
735 
736  switch_buffer_write(bp->raw_read_buffer, data, datalen);
737  } else {
738  switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen);
739  }
740 
741  if (bp->callback) {
742  ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ);
743  }
745  }
746 
747  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
749  prune++;
750  }
751  }
753  if (prune) {
755  }
756  }
757 
758  if (do_bugs || tap_only) {
759  goto done;
760  }
761 
762  if (session->read_codec) {
763  if (session->read_resampler) {
764  short *data = read_frame->data;
766  switch_resample_process(session->read_resampler, data, (int) read_frame->datalen / 2 / session->read_resampler->channels);
767  memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2 * session->read_resampler->channels);
768  read_frame->samples = session->read_resampler->to_len;
769  read_frame->channels = session->read_resampler->channels;
770  read_frame->datalen = session->read_resampler->to_len * 2 * session->read_resampler->channels;
771  read_frame->rate = session->read_resampler->to_rate;
773  }
774 
775  if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) {
776  perfect = TRUE;
777  } else {
778  if (!session->raw_read_buffer) {
780  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n",
781  (uint32_t) bytes, (uint32_t) (*frame)->datalen);
783  }
784 
785  if (read_frame->datalen && (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen))) {
786  status = SWITCH_STATUS_MEMERR;
787  goto done;
788  }
789  }
790 
791  if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) {
792  if (perfect) {
793  enc_frame = read_frame;
794  session->raw_read_frame.rate = read_frame->rate;
795  } else {
796  session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer,
797  session->raw_read_frame.data,
799 
801  enc_frame = &session->raw_read_frame;
802  }
803  session->enc_read_frame.datalen = session->enc_read_frame.buflen;
804 
805  switch_assert(session->read_codec != NULL);
806  switch_assert(enc_frame != NULL);
807  switch_assert(enc_frame->data != NULL);
808  session->read_codec->cur_frame = enc_frame;
809  enc_frame->codec->cur_frame = enc_frame;
812  status = switch_core_codec_encode(session->read_codec,
813  enc_frame->codec,
814  enc_frame->data,
815  enc_frame->datalen,
817  session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag);
819 
820  session->read_codec->cur_frame = NULL;
821  enc_frame->codec->cur_frame = NULL;
822  switch (status) {
826  session->enc_read_frame.samples = session->read_impl.decoded_bytes_per_packet / sizeof(int16_t) / session->read_impl.number_of_channels;
828  if (perfect) {
829  if (enc_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) {
830  session->enc_read_frame.timestamp = 0;
831  } else {
832  session->enc_read_frame.timestamp = read_frame->timestamp;
833  }
834  session->enc_read_frame.rate = read_frame->rate;
835  session->enc_read_frame.ssrc = read_frame->ssrc;
836  session->enc_read_frame.seq = read_frame->seq;
837  session->enc_read_frame.m = read_frame->m;
838  session->enc_read_frame.payload = session->read_impl.ianacode;
839  }
840  *frame = &session->enc_read_frame;
841  break;
842  case SWITCH_STATUS_NOOP:
845  session->raw_read_frame.timestamp = read_frame->timestamp;
846  session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode;
847  session->raw_read_frame.m = read_frame->m;
848  session->raw_read_frame.ssrc = read_frame->ssrc;
849  session->raw_read_frame.seq = read_frame->seq;
850  *frame = enc_frame;
851  status = SWITCH_STATUS_SUCCESS;
852  break;
854  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
855  *frame = NULL;
856  status = SWITCH_STATUS_GENERR;
857  break;
858  default:
859  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
861  *frame = NULL;
862  status = SWITCH_STATUS_GENERR;
863  break;
864  }
865  } else {
866  goto top;
867  }
868  }
869  }
870 
871  done:
872  if (!(*frame)) {
873  status = SWITCH_STATUS_FALSE;
874  } else {
875  if (flag & SFF_CNG) {
876  switch_set_flag((*frame), SFF_CNG);
877  }
878  if (session->bugs) {
879  switch_media_bug_t *bp;
881  int prune = 0;
883  for (bp = session->bugs; bp; bp = bp->next) {
884  ok = SWITCH_TRUE;
885 
887  continue;
888  }
889 
891  continue;
892  }
893 
895  continue;
896  }
897 
898  if (switch_test_flag(bp, SMBF_PRUNE)) {
899  prune++;
900  continue;
901  }
902 
903  if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) {
905  bp->ping_frame = *frame;
906  if (bp->callback) {
908  || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
909  ok = SWITCH_FALSE;
910  }
911  }
912  bp->ping_frame = NULL;;
914  }
915 
916  if (ok == SWITCH_FALSE) {
918  prune++;
919  }
920  }
922  if (prune) {
924  }
925  }
926  }
927 
928  even_more_done:
929 
930  if (!*frame ||
931  (!switch_test_flag(*frame, SFF_PROXY_PACKET) &&
932  (!(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)))) {
933  *frame = &runtime.dummy_cng_frame;
934  }
935 
938 
939 
942  }
943 
944 
945  return status;
946 }
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
switch_bool_t m
Definition: switch_frame.h:72
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_frame_t dummy_cng_frame
#define SWITCH_BUFFER_START_FRAMES
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_frame_t * read_replace_frame_in
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:295
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
switch_frame_t enc_read_frame
switch_read_frame_hook_t read_frame
switch_io_read_frame_t read_frame
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
switch_mutex_t * codec_read_mutex
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_bool_t
Definition: switch_types.h:405
uint32_t timestamp
Definition: switch_frame.h:69
switch_status_t switch_core_codec_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
Encode data using a codec handle.
switch_codec_t * read_codec
Representation of an event.
Definition: switch_event.h:80
switch_frame_t * cur_frame
switch_io_routines_t * io_routines
switch_status_t switch_core_codec_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
Decode data using a codec handle.
#define SWITCH_RESAMPLE_QUALITY
switch_codec_implementation_t read_impl
struct switch_io_event_hook_read_frame * next
#define switch_core_session_get_name(_s)
Definition: switch_core.h:271
uint32_t ssrc
Definition: switch_frame.h:71
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
struct switch_runtime runtime
Definition: switch_core.c:64
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_codec_t * codec
Definition: switch_frame.h:45
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
switch_media_bug_callback_t callback
uint32_t switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels)
switch_status_t switch_core_codec_reset(switch_codec_t *codec)
switch_io_event_hooks_t event_hooks
switch_mutex_t * read_mutex
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:227
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
uint16_t seq
Definition: switch_frame.h:70
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:59
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
void switch_os_yield(void)
Definition: switch_time.c:141
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
uint32_t switch_core_media_bug_prune(switch_core_session_t *session)
switch_channel_t * channel
switch_audio_resampler_t * read_resampler
uint32_t datalen
Definition: switch_frame.h:57
switch_codec_interface_t * codec_interface
switch_frame_t * ping_frame
switch_frame_flag_t flags
Definition: switch_frame.h:74
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
uint32_t rate
Definition: switch_frame.h:63
void switch_core_gen_encoded_silence(unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len)
switch_status_t switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool)
switch_media_bug_t * bugs
switch_mutex_t * resample_mutex
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
struct switch_media_bug * next
void switch_cond_next(void)
Definition: switch_time.c:638
#define switch_core_session_get_partner(_session, _partner)
Definition: switch_core.h:1002
switch_buffer_t * raw_read_buffer
Node in which to store custom read frame channel callback hooks.
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t switch_channel_dtmf_lock(switch_channel_t *channel)
switch_codec_t bug_codec
switch_frame_t raw_read_frame
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
#define switch_channel_down(_channel)
#define switch_channel_set_callstate(channel, state)
switch_status_t
Common return values.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
uint32_t samples
Definition: switch_frame.h:61
uint32_t channels
Definition: switch_frame.h:65
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
switch_ivr_dmachine_t * dmachine[2]
switch_payload_t payload
Definition: switch_frame.h:67
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
switch_channel_callstate_t switch_channel_get_callstate(switch_channel_t *channel)
switch_endpoint_interface_t * endpoint_interface
switch_mutex_t * mutex
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
#define TRUE
switch_buffer_t * raw_read_buffer
#define switch_assert(expr)
switch_frame_t * read_replace_frame_out
switch_frame_t * read_demux_frame
#define SWITCH_BUFFER_BLOCK_FRAMES
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
memset(buf, 0, buflen)
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c)
switch_frame_t * native_read_frame
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.
switch_status_t switch_channel_dtmf_unlock(switch_channel_t *channel)
switch_status_t switch_core_session_recv_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf 
)

Definition at line 1679 of file switch_core_io.c.

References switch_dtmf_t::digit, DTMF_FLAG_SENSITIVE, 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_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.

1680 {
1682  switch_status_t status;
1683  switch_dtmf_t new_dtmf;
1684  int fed = 0;
1685 
1686  if (switch_channel_down(session->channel)) {
1687  return SWITCH_STATUS_FALSE;
1688  }
1689 
1690  if (switch_test_flag(dtmf, DTMF_FLAG_SENSITIVE)) {
1691  return SWITCH_STATUS_SUCCESS;
1692  }
1693 
1694  switch_assert(dtmf);
1695 
1696  new_dtmf = *dtmf;
1697 
1698  if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
1699  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
1700  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1702  } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
1703  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
1704  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1706  } else if (!new_dtmf.duration) {
1708  }
1709 
1711  if (session->dmachine[0]) {
1712  char str[2] = { dtmf->digit, '\0' };
1713  switch_ivr_dmachine_feed(session->dmachine[0], str, NULL);
1714  fed = 1;
1715  }
1716 
1717  for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) {
1718  if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) {
1719  return status;
1720  }
1721  }
1722  }
1723 
1725 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
uint32_t duration
Definition: switch_types.h:288
uint32_t switch_core_max_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1664
switch_io_event_hooks_t event_hooks
uint32_t switch_core_min_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1704
switch_channel_t * channel
uint32_t switch_core_default_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1681
#define switch_channel_down(_channel)
switch_status_t
Common return values.
struct switch_io_event_hook_recv_dtmf * next
switch_ivr_dmachine_t * dmachine[2]
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_assert(expr)
Node in which to store custom recv dtmf channel callback hooks.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_core_session_send_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf 
)

Definition at line 1727 of file switch_core_io.c.

References CC_QUEUEABLE_DTMF_DELAY, CF_DROP_DTMF, switch_dtmf_t::digit, DTMF_FLAG_SENSITIVE, DTMF_FLAG_SKIP_PROCESS, switch_dtmf_t::duration, is_dtmf, switch_io_event_hook_send_dtmf::next, switch_io_event_hook_send_dtmf::send_dtmf, SMF_ECHO_ALEG, switch_assert, switch_channel_clear_flag(), switch_channel_down, switch_channel_get_name(), switch_channel_get_variable_dup(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_test_cap(), switch_channel_test_flag(), switch_core_default_dtmf_duration(), switch_core_max_dtmf_duration(), switch_core_min_dtmf_duration(), switch_core_session_get_uuid(), SWITCH_DTMF_SEND, SWITCH_FALSE, switch_ivr_broadcast(), switch_ivr_dmachine_feed(), switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_yield, and zstr.

Referenced by switch_core_session_send_dtmf_string().

1728 {
1731  switch_dtmf_t new_dtmf;
1732 
1733  if (switch_channel_down(session->channel)) {
1734  return SWITCH_STATUS_FALSE;
1735  }
1736 
1737  if (switch_test_flag(dtmf, DTMF_FLAG_SENSITIVE)) {
1738  return SWITCH_STATUS_SUCCESS;
1739  }
1740 
1742  const char *file = switch_channel_get_variable_dup(session->channel, "drop_dtmf_masking_file", SWITCH_FALSE, -1);
1743  const char *digits;
1744 
1745  if (!zstr(file)) {
1747  }
1748 
1749  if ((digits = switch_channel_get_variable_dup(session->channel, "drop_dtmf_masking_digits", SWITCH_FALSE, -1)) && !zstr(digits)) {
1750  const char *p;
1752 
1754  for(p = digits; p && *p; p++) {
1755  if (is_dtmf(*p)) {
1756  x_dtmf.digit = *p;
1757  switch_core_session_send_dtmf(session, &x_dtmf);
1758  }
1759  }
1761  }
1762 
1763  return SWITCH_STATUS_SUCCESS;
1764  }
1765 
1766  switch_assert(dtmf);
1767 
1768  new_dtmf = *dtmf;
1769 
1770  if (new_dtmf.digit != 'w' && new_dtmf.digit != 'W') {
1771  if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
1772  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
1773  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1775  } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
1776  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
1777  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1779  }
1780  }
1781 
1782  if (!new_dtmf.duration) {
1784  }
1785 
1787  for (ptr = session->event_hooks.send_dtmf; ptr; ptr = ptr->next) {
1788  if ((status = ptr->send_dtmf(session, dtmf, SWITCH_DTMF_SEND)) != SWITCH_STATUS_SUCCESS) {
1789  return SWITCH_STATUS_SUCCESS;
1790  }
1791  }
1792  if (session->dmachine[1]) {
1793  char str[2] = { new_dtmf.digit, '\0' };
1794  switch_ivr_dmachine_feed(session->dmachine[1], str, NULL);
1795  return SWITCH_STATUS_SUCCESS;
1796  }
1797  }
1798 
1799 
1800  if (session->endpoint_interface->io_routines->send_dtmf) {
1801  int send = 0;
1802  status = SWITCH_STATUS_SUCCESS;
1803 
1804  if (switch_channel_test_cap(session->channel, CC_QUEUEABLE_DTMF_DELAY) && (dtmf->digit == 'w' || dtmf->digit == 'W')) {
1805  send = 1;
1806  } else {
1807  if (dtmf->digit == 'w') {
1808  switch_yield(500000);
1809  } else if (dtmf->digit == 'W') {
1810  switch_yield(1000000);
1811  } else {
1812  send = 1;
1813  }
1814  }
1815 
1816  if (send) {
1817  status = session->endpoint_interface->io_routines->send_dtmf(session, &new_dtmf);
1818  }
1819  }
1820  return status;
1821 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
switch_io_send_dtmf_t send_dtmf
struct switch_io_event_hook_send_dtmf * next
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
switch_io_routines_t * io_routines
const char * switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx)
Retrieve a variable from a given channel.
uint32_t duration
Definition: switch_types.h:288
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
#define zstr(x)
Definition: switch_utils.h:281
uint32_t switch_core_max_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1664
#define is_dtmf(key)
determine if a character is a valid DTMF key
Definition: switch_utils.h:614
switch_io_event_hooks_t event_hooks
uint32_t switch_core_min_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1704
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
switch_channel_t * channel
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
uint32_t switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap)
uint32_t switch_core_default_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1681
#define switch_channel_down(_channel)
switch_status_t
Common return values.
Node in which to store custom send dtmf channel callback hooks.
#define switch_channel_set_flag(_c, _f)
switch_ivr_dmachine_t * dmachine[2]
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_endpoint_interface_t * endpoint_interface
switch_status_t switch_core_session_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define switch_assert(expr)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
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 1012 of file switch_core_io.c.

References switch_media_bug::callback, CF_ACCEPT_CNG, CF_ANSWERED, CF_AUDIO_PAUSE, CF_HOLD, CF_PASSTHRU_PTIME_MISMATCH, CF_PAUSE_BUGS, switch_frame::channels, switch_frame::codec, switch_buffer::data, switch_frame::data, switch_frame::datalen, switch_codec_implementation::ianacode, if(), switch_codec::implementation, switch_frame::m, memset(), switch_core_session_message::message_id, switch_media_bug::next, switch_core_session_message::numeric_arg, 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_CNG, SFF_NOT_AUDIO, SFF_PLC, SFF_PROXY_PACKET, SMBF_ANSWER_REQ, SMBF_NO_PAUSE, SMBF_PRUNE, SMBF_WRITE_REPLACE, SMBF_WRITE_STREAM, SSF_MEDIA_BUG_TAP_ONLY, 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_partner_uuid(), 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_CRIT, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_NOTICE, switch_log_printf(), SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY, SWITCH_MESSAGE_RESAMPLE_EVENT, switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), switch_mux_channels(), SWITCH_RECOMMENDED_BUFFER_SIZE, switch_resample_calc_buffer_size, switch_resample_create, switch_resample_destroy(), switch_resample_process(), SWITCH_RESAMPLE_QUALITY, switch_set_flag, 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.

1014 {
1015 
1017  switch_frame_t *enc_frame = NULL, *write_frame = frame;
1018  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;
1019  int did_write_resample = 0;
1020 
1021  switch_assert(session != NULL);
1022  switch_assert(frame != NULL);
1023 
1024  if (!switch_channel_ready(session->channel)) {
1025  return SWITCH_STATUS_FALSE;
1026  }
1027 
1030  } else {
1031  return SWITCH_STATUS_SUCCESS;
1032  }
1033 
1034  if (switch_test_flag(frame, SFF_CNG)) {
1036  pass_cng = 1;
1037  } else {
1038  return SWITCH_STATUS_SUCCESS;
1039  }
1040  }
1041 
1043  return SWITCH_STATUS_SUCCESS;
1044  }
1045 
1046  if (!(session->write_codec && switch_core_codec_ready(session->write_codec)) && !pass_cng) {
1047  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no write codec.\n", switch_channel_get_name(session->channel));
1049  return SWITCH_STATUS_FALSE;
1050  }
1051 
1052  if (switch_channel_test_flag(session->channel, CF_HOLD)) {
1053  return SWITCH_STATUS_SUCCESS;
1054  }
1055 
1056  if (switch_test_flag(frame, SFF_PROXY_PACKET) || pass_cng) {
1057  /* Fast PASS! */
1059  status = perform_write(session, frame, flag, stream_id);
1061  return status;
1062  }
1063 
1065 
1066  if (!(frame->codec && frame->codec->implementation)) {
1067  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has received a bad frame with no codec!\n",
1068  switch_channel_get_name(session->channel));
1071  return SWITCH_STATUS_FALSE;
1072  }
1073 
1074  switch_assert(frame->codec != NULL);
1075  switch_assert(frame->codec->implementation != NULL);
1076 
1077  if (!(switch_core_codec_ready(session->write_codec) && frame->codec) ||
1080  return SWITCH_STATUS_FALSE;
1081  }
1082 
1083  switch_mutex_lock(session->write_codec->mutex);
1084  switch_mutex_lock(frame->codec->mutex);
1085 
1086  if (!(switch_core_codec_ready(session->write_codec) && switch_core_codec_ready(frame->codec))) goto error;
1087 
1088  if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) {
1089  if (session->write_impl.codec_id == frame->codec->implementation->codec_id ||
1091  ptime_mismatch = TRUE;
1094  status = perform_write(session, frame, flags, stream_id);
1095  goto error;
1096  }
1097  }
1098  need_codec = TRUE;
1099  }
1100 
1101  if (session->write_codec && !frame->codec) {
1102  need_codec = TRUE;
1103  }
1104 
1105  if (session->bugs && !need_codec && !switch_test_flag(session, SSF_MEDIA_BUG_TAP_ONLY)) {
1106  do_bugs = TRUE;
1107  need_codec = TRUE;
1108  }
1109 
1111  need_codec = TRUE;
1112  do_resample = TRUE;
1113  }
1114 
1115 
1116  if ((frame->flags & SFF_NOT_AUDIO)) {
1117  do_resample = 0;
1118  do_bugs = 0;
1119  need_codec = 0;
1120  }
1121 
1122  if (switch_test_flag(session, SSF_WRITE_TRANSCODE) && !need_codec && switch_core_codec_ready(session->write_codec)) {
1123  switch_core_session_t *other_session;
1125 
1126  if (uuid && (other_session = switch_core_session_locate(uuid))) {
1127  switch_set_flag(other_session, SSF_READ_CODEC_RESET);
1128  switch_set_flag(other_session, SSF_READ_CODEC_RESET);
1129  switch_set_flag(other_session, SSF_WRITE_CODEC_RESET);
1130  switch_core_session_rwunlock(other_session);
1131  }
1132 
1134  }
1135 
1136 
1137  if (switch_test_flag(session, SSF_WRITE_CODEC_RESET)) {
1140  }
1141 
1142  if (!need_codec) {
1143  do_write = TRUE;
1144  write_frame = frame;
1145  goto done;
1146  }
1147 
1148  if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
1149  switch_core_session_message_t msg = { 0 };
1150 
1152  switch_core_session_receive_message(session, &msg);
1154  }
1155 
1156  if (frame->codec) {
1157  session->raw_write_frame.datalen = session->raw_write_frame.buflen;
1158  frame->codec->cur_frame = frame;
1159  session->write_codec->cur_frame = frame;
1160  status = switch_core_codec_decode(frame->codec,
1161  session->write_codec,
1162  frame->data,
1163  frame->datalen,
1165  session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags);
1166  frame->codec->cur_frame = NULL;
1167  session->write_codec->cur_frame = NULL;
1168  if (do_resample && status == SWITCH_STATUS_SUCCESS) {
1169  status = SWITCH_STATUS_RESAMPLE;
1170  }
1171 
1172  /* mux or demux to match */
1174  uint32_t rlen = session->raw_write_frame.datalen / 2 / frame->codec->implementation->number_of_channels;
1175  switch_mux_channels((int16_t *) session->raw_write_frame.data, rlen,
1177  session->raw_write_frame.datalen = rlen * 2 * session->write_impl.number_of_channels;
1178  }
1179 
1180  switch (status) {
1182  resample++;
1183  write_frame = &session->raw_write_frame;
1184  write_frame->rate = frame->codec->implementation->actual_samples_per_second;
1185  if (!session->write_resampler) {
1187  status = switch_resample_create(&session->write_resampler,
1191 
1192 
1194  if (status != SWITCH_STATUS_SUCCESS) {
1195  goto done;
1196  } else {
1197  switch_core_session_message_t msg = { 0 };
1198  msg.numeric_arg = 1;
1200  switch_core_session_receive_message(session, &msg);
1201 
1202  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
1203  }
1204  }
1205  break;
1206  case SWITCH_STATUS_SUCCESS:
1207  session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
1209  session->raw_write_frame.timestamp = frame->timestamp;
1210  session->raw_write_frame.rate = frame->rate;
1211  session->raw_write_frame.m = frame->m;
1212  session->raw_write_frame.ssrc = frame->ssrc;
1213  session->raw_write_frame.seq = frame->seq;
1214  session->raw_write_frame.payload = frame->payload;
1215  session->raw_write_frame.flags = 0;
1216  if (switch_test_flag(frame, SFF_PLC)) {
1217  session->raw_write_frame.flags |= SFF_PLC;
1218  }
1219 
1220  write_frame = &session->raw_write_frame;
1221  break;
1222  case SWITCH_STATUS_BREAK:
1223  status = SWITCH_STATUS_SUCCESS;
1224  goto error;
1225  case SWITCH_STATUS_NOOP:
1226  if (session->write_resampler) {
1229  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
1231 
1232  {
1233  switch_core_session_message_t msg = { 0 };
1234  msg.numeric_arg = 0;
1236  switch_core_session_receive_message(session, &msg);
1237  }
1238 
1239  }
1240  write_frame = frame;
1241  status = SWITCH_STATUS_SUCCESS;
1242  break;
1243  default:
1244 
1245  if (status == SWITCH_STATUS_NOT_INITALIZED) {
1246  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
1247  goto error;
1248  }
1249  if (ptime_mismatch && status != SWITCH_STATUS_GENERR) {
1250  status = perform_write(session, frame, flags, stream_id);
1251  status = SWITCH_STATUS_SUCCESS;
1252  goto error;
1253  }
1254 
1255  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n",
1257  goto error;
1258  }
1259  }
1260 
1261 
1262 
1263  if (session->write_resampler) {
1264  short *data = write_frame->data;
1265 
1267  if (session->write_resampler) {
1268 
1270  write_frame->datalen / 2 / session->write_resampler->channels) > SWITCH_RECOMMENDED_BUFFER_SIZE) {
1271 
1272  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s not enough buffer space for required resample operation!\n",
1273  switch_channel_get_name(session->channel));
1276  goto error;
1277  }
1278 
1279 
1280  switch_resample_process(session->write_resampler, data, write_frame->datalen / 2 / session->write_resampler->channels);
1281 
1282  memcpy(data, session->write_resampler->to, session->write_resampler->to_len * 2 * session->write_resampler->channels);
1283 
1284  write_frame->samples = session->write_resampler->to_len;
1285  write_frame->channels = session->write_resampler->channels;
1286  write_frame->datalen = write_frame->samples * 2 * session->write_resampler->channels;
1287 
1288  write_frame->rate = session->write_resampler->to_rate;
1289 
1290  did_write_resample = 1;
1291  }
1293  }
1294 
1295 
1296 
1297  if (session->bugs) {
1298  switch_media_bug_t *bp;
1299  int prune = 0;
1300 
1302  for (bp = session->bugs; bp; bp = bp->next) {
1304 
1305  if (!bp->ready) {
1306  continue;
1307  }
1308 
1310  continue;
1311  }
1312 
1314  continue;
1315  }
1316 
1317  if (switch_test_flag(bp, SMBF_PRUNE)) {
1318  prune++;
1319  continue;
1320  }
1321 
1324  switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen);
1326 
1327  if (bp->callback) {
1328  ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
1329  }
1330  }
1331 
1333  do_bugs = 0;
1334  if (bp->callback) {
1335  bp->write_replace_frame_in = write_frame;
1336  bp->write_replace_frame_out = write_frame;
1337  if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) {
1338  write_frame = bp->write_replace_frame_out;
1339  }
1340  }
1341  }
1342 
1343  if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) {
1344  ok = SWITCH_FALSE;
1345  }
1346 
1347 
1348  if (ok == SWITCH_FALSE) {
1350  prune++;
1351  }
1352  }
1354  if (prune) {
1355  switch_core_media_bug_prune(session);
1356  }
1357  }
1358 
1359  if (do_bugs) {
1360  do_write = TRUE;
1361  write_frame = frame;
1362  goto done;
1363  }
1364 
1365  if (session->write_codec) {
1366  if (!ptime_mismatch && write_frame->codec && write_frame->codec->implementation &&
1367  write_frame->codec->implementation->decoded_bytes_per_packet == session->write_impl.decoded_bytes_per_packet) {
1368  perfect = TRUE;
1369  }
1370 
1371 
1372 
1373  if (perfect) {
1374 
1375  if (write_frame->datalen < session->write_impl.decoded_bytes_per_packet) {
1376  memset(write_frame->data, 255, session->write_impl.decoded_bytes_per_packet - write_frame->datalen);
1377  write_frame->datalen = session->write_impl.decoded_bytes_per_packet;
1378  }
1379 
1380  enc_frame = write_frame;
1381  session->enc_write_frame.datalen = session->enc_write_frame.buflen;
1382  session->write_codec->cur_frame = frame;
1383  frame->codec->cur_frame = frame;
1386  status = switch_core_codec_encode(session->write_codec,
1387  frame->codec,
1388  enc_frame->data,
1389  enc_frame->datalen,
1391  session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
1392 
1394 
1395  session->write_codec->cur_frame = NULL;
1396  frame->codec->cur_frame = NULL;
1397  switch (status) {
1399  resample++;
1400  /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 2\n"); */
1401  case SWITCH_STATUS_SUCCESS:
1402  session->enc_write_frame.codec = session->write_codec;
1403  session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
1406  session->enc_write_frame.timestamp = 0;
1407  } else {
1408  session->enc_write_frame.timestamp = frame->timestamp;
1409  }
1410  session->enc_write_frame.payload = session->write_impl.ianacode;
1411  session->enc_write_frame.m = frame->m;
1412  session->enc_write_frame.ssrc = frame->ssrc;
1413  session->enc_write_frame.seq = frame->seq;
1414  session->enc_write_frame.flags = 0;
1415  write_frame = &session->enc_write_frame;
1416  break;
1417  case SWITCH_STATUS_NOOP:
1418  enc_frame->codec = session->write_codec;
1419  enc_frame->samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
1420  enc_frame->channels = session->write_impl.number_of_channels;
1421  enc_frame->timestamp = frame->timestamp;
1422  enc_frame->m = frame->m;
1423  enc_frame->seq = frame->seq;
1424  enc_frame->ssrc = frame->ssrc;
1425  enc_frame->payload = enc_frame->codec->implementation->ianacode;
1426  write_frame = enc_frame;
1427  status = SWITCH_STATUS_SUCCESS;
1428  break;
1430  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
1431  write_frame = NULL;
1432  goto error;
1433  default:
1434  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
1436  write_frame = NULL;
1437  goto error;
1438  }
1439  if (flag & SFF_CNG) {
1440  switch_set_flag(write_frame, SFF_CNG);
1441  }
1442 
1443  status = perform_write(session, write_frame, flags, stream_id);
1444  goto error;
1445  } else {
1446  if (!session->raw_write_buffer) {
1447  switch_size_t bytes_per_packet = session->write_impl.decoded_bytes_per_packet;
1449  "Engaging Write Buffer at %u bytes to accommodate %u->%u\n",
1450  (uint32_t) bytes_per_packet, write_frame->datalen, session->write_impl.decoded_bytes_per_packet);
1451  if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer,
1452  bytes_per_packet * SWITCH_BUFFER_BLOCK_FRAMES,
1453  bytes_per_packet * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) {
1454  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer Failed!\n");
1455  goto error;
1456  }
1457 
1458  /* Need to retrain the recording data */
1460  }
1461 
1462  if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) {
1463  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen);
1464  status = SWITCH_STATUS_MEMERR;
1465  goto error;
1466  }
1467 
1468  status = SWITCH_STATUS_SUCCESS;
1469 
1471  int rate;
1472 
1473  if (switch_channel_down(session->channel) || !session->raw_write_buffer) {
1474  goto error;
1475  }
1476  if ((session->raw_write_frame.datalen = (uint32_t)
1478  goto error;
1479  }
1480 
1481  enc_frame = &session->raw_write_frame;
1483  session->enc_write_frame.datalen = session->enc_write_frame.buflen;
1484  session->enc_write_frame.timestamp = 0;
1485 
1486 
1487  if (frame->codec && frame->codec->implementation && switch_core_codec_ready(frame->codec)) {
1489  } else {
1490  rate = session->write_impl.actual_samples_per_second;
1491  }
1492 
1493  session->write_codec->cur_frame = frame;
1494  frame->codec->cur_frame = frame;
1497  status = switch_core_codec_encode(session->write_codec,
1498  frame->codec,
1499  enc_frame->data,
1500  enc_frame->datalen,
1501  rate,
1502  session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
1503 
1505 
1506  session->write_codec->cur_frame = NULL;
1507  frame->codec->cur_frame = NULL;
1508  switch (status) {
1510  resample++;
1511  session->enc_write_frame.codec = session->write_codec;
1512  session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
1514  session->enc_write_frame.m = frame->m;
1515  session->enc_write_frame.ssrc = frame->ssrc;
1516  session->enc_write_frame.payload = session->write_impl.ianacode;
1517  write_frame = &session->enc_write_frame;
1518  if (!session->write_resampler) {
1520  if (!session->write_resampler) {
1521  status = switch_resample_create(&session->write_resampler,
1525  session->write_impl.number_of_channels);
1526  }
1528 
1529 
1530 
1531  if (status != SWITCH_STATUS_SUCCESS) {
1532  goto done;
1533  } else {
1534  switch_core_session_message_t msg = { 0 };
1535  msg.numeric_arg = 1;
1537  switch_core_session_receive_message(session, &msg);
1538 
1539 
1540  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
1541  }
1542  }
1543  break;
1544  case SWITCH_STATUS_SUCCESS:
1545  session->enc_write_frame.codec = session->write_codec;
1546  session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
1548  session->enc_write_frame.m = frame->m;
1549  session->enc_write_frame.ssrc = frame->ssrc;
1550  session->enc_write_frame.payload = session->write_impl.ianacode;
1551  session->enc_write_frame.flags = 0;
1552  write_frame = &session->enc_write_frame;
1553  break;
1554  case SWITCH_STATUS_NOOP:
1555  if (session->write_resampler) {
1556  switch_core_session_message_t msg = { 0 };
1557  int ok = 0;
1558 
1560  if (session->write_resampler) {
1562  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
1563  ok = 1;
1564  }
1566 
1567  if (ok) {
1568  msg.numeric_arg = 0;
1570  switch_core_session_receive_message(session, &msg);
1571  }
1572 
1573  }
1574  enc_frame->codec = session->write_codec;
1575  enc_frame->samples = enc_frame->datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
1576  enc_frame->channels = session->read_impl.number_of_channels;
1577  enc_frame->m = frame->m;
1578  enc_frame->ssrc = frame->ssrc;
1579  enc_frame->payload = enc_frame->codec->implementation->ianacode;
1580  write_frame = enc_frame;
1581  status = SWITCH_STATUS_SUCCESS;
1582  break;
1584  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
1585  write_frame = NULL;
1586  goto error;
1587  default:
1588  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n",
1589  session->read_codec->codec_interface->interface_name, status);
1590  write_frame = NULL;
1591  goto error;
1592  }
1593 
1594  if (!did_write_resample && session->read_resampler) {
1595  short *data = write_frame->data;
1597  if (session->read_resampler) {
1598  switch_resample_process(session->read_resampler, data, write_frame->datalen / 2 / session->read_resampler->channels);
1599  memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2 * session->read_resampler->channels);
1600  write_frame->samples = session->read_resampler->to_len;
1601  write_frame->channels = session->read_resampler->channels;
1602  write_frame->datalen = session->read_resampler->to_len * 2 * session->read_resampler->channels;
1603  write_frame->rate = session->read_resampler->to_rate;
1604  }
1606 
1607  }
1608 
1609  if (flag & SFF_CNG) {
1610  switch_set_flag(write_frame, SFF_CNG);
1611  }
1612 
1613  if (ptime_mismatch || resample) {
1614  write_frame->timestamp = 0;
1615  }
1616 
1617  if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
1618  break;
1619  }
1620 
1621  }
1622 
1623  goto error;
1624  }
1625  }
1626 
1627 
1628 
1629 
1630 
1631  done:
1632 
1633  if (ptime_mismatch || resample) {
1634  write_frame->timestamp = 0;
1635  }
1636 
1637  if (do_write) {
1638  status = perform_write(session, write_frame, flags, stream_id);
1639  }
1640 
1641  error:
1642 
1644  switch_mutex_unlock(frame->codec->mutex);
1646 
1647  return status;
1648 }
switch_frame_t * write_replace_frame_out
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
switch_bool_t m
Definition: switch_frame.h:72
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_audio_resampler_t * write_resampler
#define SWITCH_BUFFER_START_FRAMES
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:295
switch_mutex_t * codec_write_mutex
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
switch_frame_t enc_read_frame
switch_buffer_t * raw_write_buffer
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
switch_bool_t
Definition: switch_types.h:405
uint32_t timestamp
Definition: switch_frame.h:69
switch_status_t switch_core_codec_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
Encode data using a codec handle.
switch_status_t switch_core_media_bug_flush_all(_In_ switch_core_session_t *session)
Flush the read/write buffers for all media bugs on the session.
switch_codec_t * read_codec
#define switch_channel_ready(_channel)
switch_frame_t * cur_frame
#define switch_channel_media_ready(_channel)
switch_buffer_t * raw_write_buffer
switch_status_t switch_core_codec_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
Decode data using a codec handle.
#define SWITCH_RESAMPLE_QUALITY
switch_codec_implementation_t read_impl
#define switch_resample_calc_buffer_size(_to, _from, _srclen)
uint32_t ssrc
Definition: switch_frame.h:71
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_codec_t * codec
Definition: switch_frame.h:45
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
switch_media_bug_callback_t callback
switch_status_t switch_core_codec_reset(switch_codec_t *codec)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:227
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
switch_codec_implementation_t write_impl
uint16_t seq
Definition: switch_frame.h:70
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:59
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
uint32_t switch_core_media_bug_prune(switch_core_session_t *session)
switch_channel_t * channel
switch_audio_resampler_t * read_resampler
uint32_t datalen
Definition: switch_frame.h:57
switch_codec_interface_t * codec_interface
switch_byte_t * data
Definition: switch_buffer.c:43
switch_frame_flag_t flags
Definition: switch_frame.h:74
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
uint32_t rate
Definition: switch_frame.h:63
switch_codec_t * write_codec
switch_frame_t * write_replace_frame_in
switch_media_bug_t * bugs
switch_mutex_t * resample_mutex
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
struct switch_media_bug * next
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
#define switch_channel_down(_channel)
static switch_status_t perform_write(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
switch_status_t
Common return values.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
switch_frame_t enc_write_frame
uint32_t samples
Definition: switch_frame.h:61
uint32_t channels
Definition: switch_frame.h:65
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
switch_payload_t payload
Definition: switch_frame.h:67
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_mutex_t * mutex
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
#define TRUE
#define switch_assert(expr)
switch_frame_t raw_write_frame
switch_mutex_t * write_mutex
#define SWITCH_BUFFER_BLOCK_FRAMES
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
memset(buf, 0, buflen)
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c)
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.

Variable Documentation

char* SIG_NAMES[]
static
Initial value:
= {
"NONE",
"KILL",
"XFER",
"BREAK",
NULL
}

Definition at line 1650 of file switch_core_io.c.

Referenced by switch_core_session_perform_kill_channel().