File: | src/switch_core_io.c |
Location: | line 1309, column 5 |
Description: | Value stored to 'status' is never read |
1 | /* |
2 | * FreeSWITCH Moular Media Switching Software Library / Soft-Switch Application |
3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> |
4 | * |
5 | * Version: MPL 1.1 |
6 | * |
7 | * The contents of this file are subject to the Mozilla Public License Version |
8 | * 1.1 (the "License"); you may not use this file except in compliance with |
9 | * the License. You may obtain a copy of the License at |
10 | * http://www.mozilla.org/MPL/ |
11 | * |
12 | * Software distributed under the License is distributed on an "AS IS" basis, |
13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
14 | * for the specific language governing rights and limitations under the |
15 | * License. |
16 | * |
17 | * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application |
18 | * |
19 | * The Initial Developer of the Original Code is |
20 | * Anthony Minessale II <anthm@freeswitch.org> |
21 | * Portions created by the Initial Developer are Copyright (C) |
22 | * the Initial Developer. All Rights Reserved. |
23 | * |
24 | * Contributor(s): |
25 | * |
26 | * Anthony Minessale II <anthm@freeswitch.org> |
27 | * Michael Jerris <mike@jerris.com> |
28 | * Paul D. Tinsley <pdt at jackhammer.org> |
29 | * Seven Du <dujinfang@gmail.com> |
30 | * |
31 | * |
32 | * switch_core_io.c -- Main Core Library (Media I/O) |
33 | * |
34 | */ |
35 | |
36 | #include <switch.h> |
37 | #include "private/switch_core_pvt.h" |
38 | |
39 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, |
40 | int stream_id) |
41 | { |
42 | switch_io_event_hook_video_write_frame_t *ptr; |
43 | switch_status_t status = SWITCH_STATUS_FALSE; |
44 | |
45 | if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) >= CS_HANGUP )) { |
46 | return SWITCH_STATUS_FALSE; |
47 | } |
48 | |
49 | if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE)) { |
50 | return SWITCH_STATUS_SUCCESS; |
51 | } |
52 | |
53 | if (session->endpoint_interface->io_routines->write_video_frame) { |
54 | if ((status = session->endpoint_interface->io_routines->write_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { |
55 | for (ptr = session->event_hooks.video_write_frame; ptr; ptr = ptr->next) { |
56 | if ((status = ptr->video_write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { |
57 | break; |
58 | } |
59 | } |
60 | } |
61 | } |
62 | return status; |
63 | } |
64 | |
65 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, |
66 | int stream_id) |
67 | { |
68 | switch_status_t status = SWITCH_STATUS_FALSE; |
69 | switch_io_event_hook_video_read_frame_t *ptr; |
70 | |
71 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_io.c", 71, __PRETTY_FUNCTION__)); |
72 | |
73 | if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) >= CS_HANGUP )) { |
74 | return SWITCH_STATUS_FALSE; |
75 | } |
76 | |
77 | if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE)) { |
78 | *frame = &runtime.dummy_cng_frame; |
79 | switch_yield(20000)switch_sleep(20000);; |
80 | return SWITCH_STATUS_SUCCESS; |
81 | } |
82 | |
83 | if (session->endpoint_interface->io_routines->read_video_frame) { |
84 | if ((status = session->endpoint_interface->io_routines->read_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { |
85 | for (ptr = session->event_hooks.video_read_frame; ptr; ptr = ptr->next) { |
86 | if ((status = ptr->video_read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { |
87 | break; |
88 | } |
89 | } |
90 | } |
91 | } |
92 | |
93 | if (status == SWITCH_STATUS_INUSE) { |
94 | *frame = &runtime.dummy_cng_frame; |
95 | switch_yield(20000)switch_sleep(20000);; |
96 | return SWITCH_STATUS_SUCCESS; |
97 | } |
98 | |
99 | if (status != SWITCH_STATUS_SUCCESS) { |
100 | goto done; |
101 | } |
102 | |
103 | if (!(*frame)) { |
104 | goto done; |
105 | } |
106 | |
107 | switch_assert(*frame != NULL)((*frame != ((void*)0)) ? (void) (0) : __assert_fail ("*frame != ((void*)0)" , "src/switch_core_io.c", 107, __PRETTY_FUNCTION__)); |
108 | |
109 | if (switch_test_flag(*frame, SFF_CNG)((*frame)->flags & SFF_CNG)) { |
110 | status = SWITCH_STATUS_SUCCESS; |
111 | goto done; |
112 | } |
113 | |
114 | done: |
115 | |
116 | return status; |
117 | } |
118 | |
119 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_gen_encoded_silence(unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len) |
120 | { |
121 | unsigned char g729_filler[] = { |
122 | 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, |
123 | 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, |
124 | 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, |
125 | 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, |
126 | 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, |
127 | 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, |
128 | 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, |
129 | 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, |
130 | 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, |
131 | 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, |
132 | 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, |
133 | 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, |
134 | 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, |
135 | 229, 127, 79, 96, 207, 82, 216, 110, 245, 81 |
136 | }; |
137 | |
138 | |
139 | if (read_impl->ianacode == 18 || switch_stristr("g729", read_impl->iananame)) { |
140 | memcpy(data, g729_filler, len); |
141 | } else { |
142 | memset(data, 255, len); |
143 | } |
144 | |
145 | } |
146 | |
147 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, |
148 | int stream_id) |
149 | { |
150 | switch_io_event_hook_read_frame_t *ptr; |
151 | switch_status_t status = SWITCH_STATUS_FALSE; |
152 | int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0, tap_only = 0; |
153 | switch_codec_implementation_t codec_impl; |
154 | unsigned int flag = 0; |
155 | int i; |
156 | |
157 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_io.c", 157, __PRETTY_FUNCTION__)); |
158 | |
159 | tap_only = switch_test_flag(session, SSF_MEDIA_BUG_TAP_ONLY)((session)->flags & SSF_MEDIA_BUG_TAP_ONLY); |
160 | |
161 | switch_os_yield(); |
162 | |
163 | if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) { |
164 | switch_mutex_unlock(session->codec_read_mutex); |
165 | } else { |
166 | switch_cond_next(); |
167 | *frame = &runtime.dummy_cng_frame; |
168 | return SWITCH_STATUS_SUCCESS; |
169 | } |
170 | |
171 | if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) { |
172 | if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_get_state(session->channel) == CS_HIBERNATE) { |
173 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 173, (const char*)(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n", |
174 | switch_channel_get_name(session->channel)); |
175 | switch_cond_next(); |
176 | *frame = &runtime.dummy_cng_frame; |
177 | return SWITCH_STATUS_SUCCESS; |
178 | } |
179 | |
180 | if (switch_channel_test_flag(session->channel, CF_AUDIO_PAUSE)) { |
181 | switch_yield(20000)switch_sleep(20000);; |
182 | *frame = &runtime.dummy_cng_frame; |
183 | // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Media Paused!!!!\n"); |
184 | return SWITCH_STATUS_SUCCESS; |
185 | } |
186 | |
187 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 187, (const char*)(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); |
188 | switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_io.c" , (const char *)__func__, 188, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ); |
189 | return SWITCH_STATUS_FALSE; |
190 | } |
191 | |
192 | switch_mutex_lock(session->codec_read_mutex); |
193 | |
194 | if (!switch_core_codec_ready(session->read_codec)) { |
195 | switch_mutex_unlock(session->codec_read_mutex); |
196 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 196, (const char*)(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); |
197 | switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_io.c" , (const char *)__func__, 197, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ); |
198 | *frame = &runtime.dummy_cng_frame; |
199 | return SWITCH_STATUS_FALSE; |
200 | } |
201 | |
202 | switch_mutex_lock(session->read_codec->mutex); |
203 | |
204 | top: |
205 | |
206 | for(i = 0; i < 2; i++) { |
207 | if (session->dmachine[i]) { |
208 | switch_channel_dtmf_lock(session->channel); |
209 | switch_ivr_dmachine_ping(session->dmachine[i], NULL((void*)0)); |
210 | switch_channel_dtmf_unlock(session->channel); |
211 | } |
212 | } |
213 | |
214 | if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) >= CS_HANGUP ) || !switch_core_codec_ready(session->read_codec)) { |
215 | *frame = NULL((void*)0); |
216 | status = SWITCH_STATUS_FALSE; |
217 | goto even_more_done; |
218 | } |
219 | |
220 | |
221 | status = SWITCH_STATUS_FALSE; |
222 | need_codec = perfect = 0; |
223 | |
224 | *frame = NULL((void*)0); |
225 | |
226 | if (session->read_codec && !session->track_id && session->track_duration) { |
227 | if (session->read_frame_count == 0) { |
228 | switch_event_t *event; |
229 | switch_core_session_message_t msg = { 0 }; |
230 | |
231 | session->read_frame_count = (session->read_impl.samples_per_second / session->read_impl.samples_per_packet) * session->track_duration; |
232 | |
233 | msg.message_id = SWITCH_MESSAGE_HEARTBEAT_EVENT; |
234 | msg.numeric_arg = session->track_duration; |
235 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 235); |
236 | |
237 | switch_event_create(&event, SWITCH_EVENT_SESSION_HEARTBEAT)switch_event_create_subclass_detailed("src/switch_core_io.c", (const char * )(const char *)__func__, 237, &event, SWITCH_EVENT_SESSION_HEARTBEAT , ((void*)0)); |
238 | switch_channel_event_set_data(session->channel, event); |
239 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_io.c", (const char * )(const char *)__func__, 239, &event, ((void*)0)); |
240 | } else { |
241 | session->read_frame_count--; |
242 | } |
243 | } |
244 | |
245 | |
246 | if (switch_channel_test_flag(session->channel, CF_HOLD)) { |
247 | switch_yield(session->read_impl.microseconds_per_packet)switch_sleep(session->read_impl.microseconds_per_packet);; |
248 | status = SWITCH_STATUS_BREAK; |
249 | goto even_more_done; |
250 | } |
251 | |
252 | if (session->endpoint_interface->io_routines->read_frame) { |
253 | switch_mutex_unlock(session->read_codec->mutex); |
254 | switch_mutex_unlock(session->codec_read_mutex); |
255 | if ((status = session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { |
256 | for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) { |
257 | if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { |
258 | break; |
259 | } |
260 | } |
261 | } |
262 | |
263 | if (status == SWITCH_STATUS_INUSE) { |
264 | *frame = &runtime.dummy_cng_frame; |
265 | switch_yield(20000)switch_sleep(20000);; |
266 | return SWITCH_STATUS_SUCCESS; |
267 | } |
268 | |
269 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) { |
270 | *frame = NULL((void*)0); |
271 | return SWITCH_STATUS_FALSE; |
272 | } |
273 | |
274 | switch_mutex_lock(session->codec_read_mutex); |
275 | |
276 | if (!switch_core_codec_ready(session->read_codec)) { |
277 | switch_mutex_unlock(session->codec_read_mutex); |
278 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 278, (const char*)(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); |
279 | switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_io.c" , (const char *)__func__, 279, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ); |
280 | *frame = &runtime.dummy_cng_frame; |
281 | return SWITCH_STATUS_FALSE; |
282 | } |
283 | |
284 | switch_mutex_lock(session->read_codec->mutex); |
285 | if (!switch_core_codec_ready(session->read_codec)) { |
286 | *frame = NULL((void*)0); |
287 | status = SWITCH_STATUS_FALSE; |
288 | goto even_more_done; |
289 | } |
290 | } |
291 | |
292 | if (status != SWITCH_STATUS_SUCCESS) { |
293 | goto done; |
294 | } |
295 | |
296 | if (!(*frame)) { |
297 | goto done; |
298 | } |
299 | |
300 | switch_assert(*frame != NULL)((*frame != ((void*)0)) ? (void) (0) : __assert_fail ("*frame != ((void*)0)" , "src/switch_core_io.c", 300, __PRETTY_FUNCTION__)); |
301 | |
302 | if (switch_test_flag(*frame, SFF_PROXY_PACKET)((*frame)->flags & SFF_PROXY_PACKET)) { |
303 | /* Fast PASS! */ |
304 | status = SWITCH_STATUS_SUCCESS; |
305 | goto done; |
306 | } |
307 | |
308 | switch_assert((*frame)->codec != NULL)(((*frame)->codec != ((void*)0)) ? (void) (0) : __assert_fail ("(*frame)->codec != ((void*)0)", "src/switch_core_io.c", 308, __PRETTY_FUNCTION__)); |
309 | |
310 | if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) { |
311 | status = SWITCH_STATUS_FALSE; |
312 | goto done; |
313 | } |
314 | |
315 | if (session->bugs && !((*frame)->flags & SFF_CNG) && !((*frame)->flags & SFF_NOT_AUDIO)) { |
316 | switch_media_bug_t *bp; |
317 | switch_bool_t ok = SWITCH_TRUE; |
318 | int prune = 0; |
319 | |
320 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
321 | |
322 | for (bp = session->bugs; bp; bp = bp->next) { |
323 | ok = SWITCH_TRUE; |
324 | |
325 | if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { |
326 | continue; |
327 | } |
328 | |
329 | if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { |
330 | continue; |
331 | } |
332 | if (switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE)) { |
333 | prune++; |
334 | continue; |
335 | } |
336 | |
337 | if (bp->ready) { |
338 | if (switch_test_flag(bp, SMBF_TAP_NATIVE_READ)((bp)->flags & SMBF_TAP_NATIVE_READ)) { |
339 | if ((*frame)->codec && (*frame)->codec->implementation && |
340 | (*frame)->codec->implementation->encoded_bytes_per_packet && |
341 | (*frame)->datalen != (*frame)->codec->implementation->encoded_bytes_per_packet) { |
342 | switch_set_flag((*frame), SFF_CNG)((*frame))->flags |= (SFF_CNG); |
343 | break; |
344 | } |
345 | if (bp->callback) { |
346 | bp->native_read_frame = *frame; |
347 | ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_TAP_NATIVE_READ); |
348 | bp->native_read_frame = NULL((void*)0); |
349 | } |
350 | } |
351 | } |
352 | |
353 | if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL((void*)0))) || ok == SWITCH_FALSE) { |
354 | switch_set_flag(bp, SMBF_PRUNE)(bp)->flags |= (SMBF_PRUNE); |
355 | prune++; |
356 | } |
357 | } |
358 | switch_thread_rwlock_unlock(session->bug_rwlock); |
359 | |
360 | if (prune) { |
361 | switch_core_media_bug_prune(session); |
362 | } |
363 | } |
364 | |
365 | codec_impl = *(*frame)->codec->implementation; |
366 | |
367 | if (session->read_codec->implementation->impl_id != codec_impl.impl_id) { |
368 | need_codec = TRUE(!0); |
369 | tap_only = 0; |
370 | } |
371 | |
372 | if (codec_impl.actual_samples_per_second != session->read_impl.actual_samples_per_second) { |
373 | do_resample = 1; |
374 | } |
375 | |
376 | if (tap_only) { |
377 | switch_media_bug_t *bp; |
378 | switch_bool_t ok = SWITCH_TRUE; |
379 | int prune = 0; |
380 | |
381 | if (session->bugs && switch_test_flag((*frame), SFF_CNG)(((*frame))->flags & SFF_CNG)) { |
382 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
383 | for (bp = session->bugs; bp; bp = bp->next) { |
384 | ok = SWITCH_TRUE; |
385 | |
386 | if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { |
387 | continue; |
388 | } |
389 | |
390 | if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { |
391 | continue; |
392 | } |
393 | if (switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE)) { |
394 | prune++; |
395 | continue; |
396 | } |
397 | |
398 | if (bp->ready && (*frame)->codec && (*frame)->codec->implementation && (*frame)->codec->implementation->encoded_bytes_per_packet) { |
399 | if (switch_test_flag(bp, SMBF_TAP_NATIVE_READ)((bp)->flags & SMBF_TAP_NATIVE_READ)) { |
400 | if (bp->callback) { |
401 | switch_frame_t tmp_frame = {0}; |
402 | unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = {0}; |
403 | |
404 | |
405 | tmp_frame.codec = (*frame)->codec; |
406 | tmp_frame.datalen = (*frame)->codec->implementation->encoded_bytes_per_packet; |
407 | tmp_frame.samples = (*frame)->codec->implementation->samples_per_packet; |
408 | tmp_frame.channels = (*frame)->codec->implementation->number_of_channels; |
409 | tmp_frame.data = data; |
410 | |
411 | switch_core_gen_encoded_silence(data, (*frame)->codec->implementation, tmp_frame.datalen); |
412 | |
413 | bp->native_read_frame = &tmp_frame; |
414 | ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_TAP_NATIVE_READ); |
415 | bp->native_read_frame = NULL((void*)0); |
416 | } |
417 | } |
418 | } |
419 | |
420 | if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL((void*)0))) || ok == SWITCH_FALSE) { |
421 | switch_set_flag(bp, SMBF_PRUNE)(bp)->flags |= (SMBF_PRUNE); |
422 | prune++; |
423 | } |
424 | } |
425 | switch_thread_rwlock_unlock(session->bug_rwlock); |
426 | |
427 | if (prune) { |
428 | switch_core_media_bug_prune(session); |
429 | } |
430 | |
431 | |
432 | } |
433 | |
434 | |
435 | goto done; |
436 | } else if (session->bugs && !need_codec) { |
437 | do_bugs = 1; |
438 | need_codec = 1; |
439 | } |
440 | |
441 | if (switch_test_flag(*frame, SFF_CNG)((*frame)->flags & SFF_CNG)) { |
442 | if (!session->bugs && !session->plc) { |
443 | /* Check if other session has bugs */ |
444 | unsigned int other_session_bugs = 0; |
445 | switch_core_session_t *other_session = NULL((void*)0); |
446 | if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_BRIDGED) && |
447 | switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session , "src/switch_core_io.c", (const char *)__func__, 447) == SWITCH_STATUS_SUCCESS) { |
448 | if (other_session->bugs && !switch_test_flag(other_session, SSF_MEDIA_BUG_TAP_ONLY)((other_session)->flags & SSF_MEDIA_BUG_TAP_ONLY)) { |
449 | other_session_bugs = 1; |
450 | } |
451 | switch_core_session_rwunlock(other_session); |
452 | } |
453 | |
454 | /* Don't process CNG frame */ |
455 | if (!other_session_bugs) { |
456 | status = SWITCH_STATUS_SUCCESS; |
457 | goto done; |
458 | } |
459 | } |
460 | is_cng = 1; |
461 | need_codec = 1; |
462 | } else if (switch_test_flag(*frame, SFF_NOT_AUDIO)((*frame)->flags & SFF_NOT_AUDIO)) { |
463 | do_resample = 0; |
464 | do_bugs = 0; |
465 | need_codec = 0; |
466 | } |
467 | |
468 | if (switch_test_flag(session, SSF_READ_TRANSCODE)((session)->flags & SSF_READ_TRANSCODE) && !need_codec && switch_core_codec_ready(session->read_codec)) { |
469 | switch_core_session_t *other_session; |
470 | const char *uuid = switch_channel_get_partner_uuid(switch_core_session_get_channel(session)); |
471 | switch_clear_flag(session, SSF_READ_TRANSCODE)(session)->flags &= ~(SSF_READ_TRANSCODE); |
472 | |
473 | if (uuid && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_core_io.c" , (const char *)__func__, 473))) { |
474 | switch_set_flag(other_session, SSF_READ_CODEC_RESET)(other_session)->flags |= (SSF_READ_CODEC_RESET); |
475 | switch_set_flag(other_session, SSF_READ_CODEC_RESET)(other_session)->flags |= (SSF_READ_CODEC_RESET); |
476 | switch_set_flag(other_session, SSF_WRITE_CODEC_RESET)(other_session)->flags |= (SSF_WRITE_CODEC_RESET); |
477 | switch_core_session_rwunlock(other_session); |
478 | } |
479 | } |
480 | |
481 | if (switch_test_flag(session, SSF_READ_CODEC_RESET)((session)->flags & SSF_READ_CODEC_RESET)) { |
482 | switch_core_codec_reset(session->read_codec); |
483 | switch_clear_flag(session, SSF_READ_CODEC_RESET)(session)->flags &= ~(SSF_READ_CODEC_RESET); |
484 | } |
485 | |
486 | |
487 | if (status == SWITCH_STATUS_SUCCESS && need_codec) { |
488 | switch_frame_t *enc_frame, *read_frame = *frame; |
489 | |
490 | switch_set_flag(session, SSF_READ_TRANSCODE)(session)->flags |= (SSF_READ_TRANSCODE); |
491 | |
492 | if (!switch_test_flag(session, SSF_WARN_TRANSCODE)((session)->flags & SSF_WARN_TRANSCODE)) { |
493 | switch_core_session_message_t msg = { 0 }; |
494 | |
495 | msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY; |
496 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 496); |
497 | switch_set_flag(session, SSF_WARN_TRANSCODE)(session)->flags |= (SSF_WARN_TRANSCODE); |
498 | } |
499 | |
500 | if (read_frame->codec || is_cng) { |
501 | session->raw_read_frame.datalen = session->raw_read_frame.buflen; |
502 | |
503 | if (is_cng) { |
504 | if (session->plc) { |
505 | plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2); |
506 | is_cng = 0; |
507 | flag &= ~SFF_CNG; |
508 | } else { |
509 | memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); |
510 | } |
511 | |
512 | session->raw_read_frame.timestamp = 0; |
513 | session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; |
514 | session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels; |
515 | session->raw_read_frame.channels = read_frame->codec->implementation->number_of_channels; |
516 | read_frame = &session->raw_read_frame; |
517 | status = SWITCH_STATUS_SUCCESS; |
518 | } else { |
519 | switch_codec_t *use_codec = read_frame->codec; |
520 | if (do_bugs) { |
521 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
522 | if (!session->bugs) { |
523 | switch_thread_rwlock_unlock(session->bug_rwlock); |
524 | goto done; |
525 | } |
526 | |
527 | if (!switch_core_codec_ready(&session->bug_codec) && switch_core_codec_ready(read_frame->codec)) { |
528 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 528, (const char*)(session), SWITCH_LOG_DEBUG, "Setting BUG Codec %s:%d\n", |
529 | read_frame->codec->implementation->iananame, read_frame->codec->implementation->ianacode); |
530 | switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL((void*)0)); |
531 | if (!switch_core_codec_ready(&session->bug_codec)) { |
532 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 532, (const char*)(session), SWITCH_LOG_ERROR, "%s Error setting BUG codec %s!\n", |
533 | switch_core_session_get_name(session)switch_channel_get_name(switch_core_session_get_channel(session )), read_frame->codec->implementation->iananame); |
534 | } |
535 | } |
536 | |
537 | if (switch_core_codec_ready(&session->bug_codec)) { |
538 | use_codec = &session->bug_codec; |
539 | } |
540 | switch_thread_rwlock_unlock(session->bug_rwlock); |
541 | |
542 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
543 | if (!session->bugs) { |
544 | do_bugs = 0; |
545 | } |
546 | switch_thread_rwlock_unlock(session->bug_rwlock); |
547 | if (!do_bugs) goto done; |
548 | } |
549 | |
550 | if (switch_test_flag(read_frame, SFF_PLC)((read_frame)->flags & SFF_PLC)) { |
551 | session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; |
552 | session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels; |
553 | session->raw_read_frame.channels = session->read_impl.number_of_channels; |
554 | memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen); |
555 | status = SWITCH_STATUS_SUCCESS; |
556 | } else { |
557 | switch_codec_t *codec = use_codec; |
558 | |
559 | if (!switch_core_codec_ready(codec)) { |
560 | codec = read_frame->codec; |
561 | } |
562 | |
563 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
564 | codec->cur_frame = read_frame; |
565 | session->read_codec->cur_frame = read_frame; |
566 | status = switch_core_codec_decode(codec, |
567 | session->read_codec, |
568 | read_frame->data, |
569 | read_frame->datalen, |
570 | session->read_impl.actual_samples_per_second, |
571 | session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, |
572 | &read_frame->flags); |
573 | codec->cur_frame = NULL((void*)0); |
574 | session->read_codec->cur_frame = NULL((void*)0); |
575 | switch_thread_rwlock_unlock(session->bug_rwlock); |
576 | |
577 | } |
578 | |
579 | if (status == SWITCH_STATUS_SUCCESS && session->read_impl.number_of_channels == 1) { |
580 | if ((switch_channel_test_flag(session->channel, CF_JITTERBUFFER_PLC) || switch_channel_test_flag(session->channel, CF_CNG_PLC)) |
581 | && !session->plc) { |
582 | session->plc = plc_init(NULL((void*)0)); |
583 | } |
584 | |
585 | if (session->plc) { |
586 | if (switch_test_flag(read_frame, SFF_PLC)((read_frame)->flags & SFF_PLC)) { |
587 | plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); |
588 | switch_clear_flag(read_frame, SFF_PLC)(read_frame)->flags &= ~(SFF_PLC); |
589 | } else { |
590 | plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); |
591 | } |
592 | } |
593 | } |
594 | |
595 | |
596 | } |
597 | |
598 | if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) { |
599 | status = SWITCH_STATUS_RESAMPLE; |
600 | } |
601 | |
602 | /* mux or demux to match */ |
603 | if (session->read_impl.number_of_channels != read_frame->codec->implementation->number_of_channels) { |
604 | uint32_t rlen = session->raw_read_frame.datalen / 2 / read_frame->codec->implementation->number_of_channels; |
605 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 605, (const char*)(session), SWITCH_LOG_WARNING, "%s MUX READ\n", switch_channel_get_name(session->channel)); |
606 | switch_mux_channels((int16_t *) session->raw_read_frame.data, rlen, |
607 | read_frame->codec->implementation->number_of_channels, session->read_impl.number_of_channels); |
608 | session->raw_write_frame.datalen = rlen * 2 * session->read_impl.number_of_channels; |
609 | } |
610 | |
611 | switch (status) { |
612 | case SWITCH_STATUS_RESAMPLE: |
613 | if (!session->read_resampler) { |
614 | switch_mutex_lock(session->resample_mutex); |
615 | |
616 | status = switch_resample_create(&session->read_resampler,switch_resample_perform_create(&session->read_resampler , read_frame->codec->implementation->actual_samples_per_second , session->read_impl.actual_samples_per_second, session-> read_impl.decoded_bytes_per_packet, 2, session->read_impl. number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 620) |
617 | read_frame->codec->implementation->actual_samples_per_second,switch_resample_perform_create(&session->read_resampler , read_frame->codec->implementation->actual_samples_per_second , session->read_impl.actual_samples_per_second, session-> read_impl.decoded_bytes_per_packet, 2, session->read_impl. number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 620) |
618 | session->read_impl.actual_samples_per_second,switch_resample_perform_create(&session->read_resampler , read_frame->codec->implementation->actual_samples_per_second , session->read_impl.actual_samples_per_second, session-> read_impl.decoded_bytes_per_packet, 2, session->read_impl. number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 620) |
619 | session->read_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY,switch_resample_perform_create(&session->read_resampler , read_frame->codec->implementation->actual_samples_per_second , session->read_impl.actual_samples_per_second, session-> read_impl.decoded_bytes_per_packet, 2, session->read_impl. number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 620) |
620 | session->read_impl.number_of_channels)switch_resample_perform_create(&session->read_resampler , read_frame->codec->implementation->actual_samples_per_second , session->read_impl.actual_samples_per_second, session-> read_impl.decoded_bytes_per_packet, 2, session->read_impl. number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 620); |
621 | |
622 | switch_mutex_unlock(session->resample_mutex); |
623 | |
624 | if (status != SWITCH_STATUS_SUCCESS) { |
625 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 625, (const char*)(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n"); |
626 | status = SWITCH_STATUS_FALSE; |
627 | goto done; |
628 | } else { |
629 | switch_core_session_message_t msg = { 0 }; |
630 | msg.numeric_arg = 1; |
631 | msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT; |
632 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 632); |
633 | |
634 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 634, (const char*)(session), SWITCH_LOG_NOTICE, "Activating read resampler\n"); |
635 | } |
636 | } |
637 | case SWITCH_STATUS_SUCCESS: |
638 | session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels; |
639 | session->raw_read_frame.channels = session->read_impl.number_of_channels; |
640 | session->raw_read_frame.rate = read_frame->rate; |
641 | if (read_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { |
642 | session->raw_read_frame.timestamp = 0; |
643 | } else { |
644 | session->raw_read_frame.timestamp = read_frame->timestamp; |
645 | } |
646 | session->raw_read_frame.ssrc = read_frame->ssrc; |
647 | session->raw_read_frame.seq = read_frame->seq; |
648 | session->raw_read_frame.m = read_frame->m; |
649 | session->raw_read_frame.payload = read_frame->payload; |
650 | session->raw_read_frame.flags = 0; |
651 | if (switch_test_flag(read_frame, SFF_PLC)((read_frame)->flags & SFF_PLC)) { |
652 | session->raw_read_frame.flags |= SFF_PLC; |
653 | } |
654 | read_frame = &session->raw_read_frame; |
655 | break; |
656 | case SWITCH_STATUS_NOOP: |
657 | if (session->read_resampler) { |
658 | switch_mutex_lock(session->resample_mutex); |
659 | switch_resample_destroy(&session->read_resampler); |
660 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 660, (const char*)(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n"); |
661 | switch_mutex_unlock(session->resample_mutex); |
662 | |
663 | { |
664 | switch_core_session_message_t msg = { 0 }; |
665 | msg.numeric_arg = 0; |
666 | msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT; |
667 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 667); |
668 | } |
669 | |
670 | } |
671 | |
672 | status = SWITCH_STATUS_SUCCESS; |
673 | break; |
674 | case SWITCH_STATUS_BREAK: |
675 | memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); |
676 | session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; |
677 | session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels; |
678 | session->raw_read_frame.channels = session->read_impl.number_of_channels; |
679 | session->raw_read_frame.timestamp = read_frame->timestamp; |
680 | session->raw_read_frame.rate = read_frame->rate; |
681 | session->raw_read_frame.ssrc = read_frame->ssrc; |
682 | session->raw_read_frame.seq = read_frame->seq; |
683 | session->raw_read_frame.m = read_frame->m; |
684 | session->raw_read_frame.payload = read_frame->payload; |
685 | session->raw_read_frame.flags = 0; |
686 | if (switch_test_flag(read_frame, SFF_PLC)((read_frame)->flags & SFF_PLC)) { |
687 | session->raw_read_frame.flags |= SFF_PLC; |
688 | } |
689 | |
690 | read_frame = &session->raw_read_frame; |
691 | status = SWITCH_STATUS_SUCCESS; |
692 | break; |
693 | case SWITCH_STATUS_NOT_INITALIZED: |
694 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 694, (const char*)(session), SWITCH_LOG_ERROR, "Codec init error!\n"); |
695 | goto done; |
696 | default: |
697 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 697, (const char*)(session), SWITCH_LOG_ERROR, "Codec %s decoder error! [%d]\n", |
698 | session->read_codec->codec_interface->interface_name, status); |
699 | |
700 | if (++session->decoder_errors < 10) { |
701 | status = SWITCH_STATUS_SUCCESS; |
702 | } else { |
703 | goto done; |
704 | } |
705 | } |
706 | |
707 | session->decoder_errors = 0; |
708 | } |
709 | |
710 | if (session->bugs) { |
711 | switch_media_bug_t *bp; |
712 | switch_bool_t ok = SWITCH_TRUE; |
713 | int prune = 0; |
714 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
715 | |
716 | for (bp = session->bugs; bp; bp = bp->next) { |
717 | ok = SWITCH_TRUE; |
718 | |
719 | if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { |
720 | continue; |
721 | } |
722 | |
723 | if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { |
724 | continue; |
725 | } |
726 | |
727 | if (!switch_channel_test_flag(session->channel, CF_BRIDGED) && switch_core_media_bug_test_flag(bp, SMBF_BRIDGE_REQ)) { |
728 | continue; |
729 | } |
730 | |
731 | if (switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE)) { |
732 | prune++; |
733 | continue; |
734 | } |
735 | |
736 | if (ok && switch_test_flag(bp, SMBF_READ_REPLACE)((bp)->flags & SMBF_READ_REPLACE)) { |
737 | do_bugs = 0; |
738 | if (bp->callback) { |
739 | bp->read_replace_frame_in = read_frame; |
740 | bp->read_replace_frame_out = read_frame; |
741 | bp->read_demux_frame = NULL((void*)0); |
742 | if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) { |
743 | read_frame = bp->read_replace_frame_out; |
744 | } |
745 | } |
746 | } |
747 | |
748 | if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL((void*)0))) || ok == SWITCH_FALSE) { |
749 | switch_set_flag(bp, SMBF_PRUNE)(bp)->flags |= (SMBF_PRUNE); |
750 | prune++; |
751 | } |
752 | |
753 | |
754 | } |
755 | switch_thread_rwlock_unlock(session->bug_rwlock); |
756 | if (prune) { |
757 | switch_core_media_bug_prune(session); |
758 | } |
759 | } |
760 | |
761 | if (session->bugs) { |
762 | switch_media_bug_t *bp; |
763 | switch_bool_t ok = SWITCH_TRUE; |
764 | int prune = 0; |
765 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
766 | |
767 | for (bp = session->bugs; bp; bp = bp->next) { |
768 | ok = SWITCH_TRUE; |
769 | |
770 | if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { |
771 | continue; |
772 | } |
773 | |
774 | if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { |
775 | continue; |
776 | } |
777 | |
778 | if (!switch_channel_test_flag(session->channel, CF_BRIDGED) && switch_core_media_bug_test_flag(bp, SMBF_BRIDGE_REQ)) { |
779 | continue; |
780 | } |
781 | |
782 | if (switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE)) { |
783 | prune++; |
784 | continue; |
785 | } |
786 | |
787 | if (ok && bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)((bp)->flags & SMBF_READ_STREAM)) { |
788 | switch_mutex_lock(bp->read_mutex); |
789 | if (bp->read_demux_frame) { |
790 | uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE8192]; |
791 | int bytes = read_frame->datalen / 2; |
792 | |
793 | memcpy(data, read_frame->data, read_frame->datalen); |
794 | switch_unmerge_sln((int16_t *)data, bytes, bp->read_demux_frame->data, bytes); |
795 | switch_buffer_write(bp->raw_read_buffer, data, read_frame->datalen); |
796 | } else { |
797 | switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen); |
798 | } |
799 | |
800 | if (bp->callback) { |
801 | ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ); |
802 | } |
803 | switch_mutex_unlock(bp->read_mutex); |
804 | } |
805 | |
806 | if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL((void*)0))) || ok == SWITCH_FALSE) { |
807 | switch_set_flag(bp, SMBF_PRUNE)(bp)->flags |= (SMBF_PRUNE); |
808 | prune++; |
809 | } |
810 | } |
811 | switch_thread_rwlock_unlock(session->bug_rwlock); |
812 | if (prune) { |
813 | switch_core_media_bug_prune(session); |
814 | } |
815 | } |
816 | |
817 | if (do_bugs || tap_only) { |
818 | goto done; |
819 | } |
820 | |
821 | if (session->read_codec) { |
822 | if (session->read_resampler) { |
823 | short *data = read_frame->data; |
824 | switch_mutex_lock(session->resample_mutex); |
825 | switch_resample_process(session->read_resampler, data, (int) read_frame->datalen / 2 / session->read_resampler->channels); |
826 | memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2 * session->read_resampler->channels); |
827 | read_frame->samples = session->read_resampler->to_len; |
828 | read_frame->channels = session->read_resampler->channels; |
829 | read_frame->datalen = session->read_resampler->to_len * 2 * session->read_resampler->channels; |
830 | read_frame->rate = session->read_resampler->to_rate; |
831 | switch_mutex_unlock(session->resample_mutex); |
832 | } |
833 | |
834 | if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) { |
835 | perfect = TRUE(!0); |
836 | } else { |
837 | if (!session->raw_read_buffer) { |
838 | switch_size_t bytes = session->read_impl.decoded_bytes_per_packet; |
839 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 839, (const char*)(session), SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n", |
840 | (uint32_t) bytes, (uint32_t) (*frame)->datalen); |
841 | switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES25, bytes * SWITCH_BUFFER_START_FRAMES50, 0); |
842 | } |
843 | |
844 | if (read_frame->datalen && (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen))) { |
845 | status = SWITCH_STATUS_MEMERR; |
846 | goto done; |
847 | } |
848 | } |
849 | |
850 | if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) { |
851 | if (perfect) { |
852 | enc_frame = read_frame; |
853 | session->raw_read_frame.rate = read_frame->rate; |
854 | } else { |
855 | session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer, |
856 | session->raw_read_frame.data, |
857 | session->read_impl.decoded_bytes_per_packet); |
858 | |
859 | session->raw_read_frame.rate = session->read_impl.actual_samples_per_second; |
860 | enc_frame = &session->raw_read_frame; |
861 | } |
862 | session->enc_read_frame.datalen = session->enc_read_frame.buflen; |
863 | |
864 | switch_assert(session->read_codec != NULL)((session->read_codec != ((void*)0)) ? (void) (0) : __assert_fail ("session->read_codec != ((void*)0)", "src/switch_core_io.c" , 864, __PRETTY_FUNCTION__)); |
865 | switch_assert(enc_frame != NULL)((enc_frame != ((void*)0)) ? (void) (0) : __assert_fail ("enc_frame != ((void*)0)" , "src/switch_core_io.c", 865, __PRETTY_FUNCTION__)); |
866 | switch_assert(enc_frame->data != NULL)((enc_frame->data != ((void*)0)) ? (void) (0) : __assert_fail ("enc_frame->data != ((void*)0)", "src/switch_core_io.c", 866, __PRETTY_FUNCTION__)); |
867 | session->read_codec->cur_frame = enc_frame; |
868 | enc_frame->codec->cur_frame = enc_frame; |
869 | switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((enc_frame->datalen <= 8192) ? (void) (0) : __assert_fail ("enc_frame->datalen <= 8192", "src/switch_core_io.c", 869, __PRETTY_FUNCTION__)); |
870 | switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((session->enc_read_frame.datalen <= 8192) ? (void) (0) : __assert_fail ("session->enc_read_frame.datalen <= 8192" , "src/switch_core_io.c", 870, __PRETTY_FUNCTION__)); |
871 | status = switch_core_codec_encode(session->read_codec, |
872 | enc_frame->codec, |
873 | enc_frame->data, |
874 | enc_frame->datalen, |
875 | session->read_impl.actual_samples_per_second, |
876 | session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag); |
877 | switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((session->enc_read_frame.datalen <= 8192) ? (void) (0) : __assert_fail ("session->enc_read_frame.datalen <= 8192" , "src/switch_core_io.c", 877, __PRETTY_FUNCTION__)); |
878 | |
879 | session->read_codec->cur_frame = NULL((void*)0); |
880 | enc_frame->codec->cur_frame = NULL((void*)0); |
881 | switch (status) { |
882 | case SWITCH_STATUS_RESAMPLE: |
883 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 883, (const char*)(session), SWITCH_LOG_DEBUG, "Fixme 1\n"); |
884 | case SWITCH_STATUS_SUCCESS: |
885 | session->enc_read_frame.samples = session->read_impl.decoded_bytes_per_packet / sizeof(int16_t) / session->read_impl.number_of_channels; |
886 | session->enc_read_frame.channels = session->read_impl.number_of_channels; |
887 | if (perfect) { |
888 | if (enc_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { |
889 | session->enc_read_frame.timestamp = 0; |
890 | } else { |
891 | session->enc_read_frame.timestamp = read_frame->timestamp; |
892 | } |
893 | session->enc_read_frame.rate = read_frame->rate; |
894 | session->enc_read_frame.ssrc = read_frame->ssrc; |
895 | session->enc_read_frame.seq = read_frame->seq; |
896 | session->enc_read_frame.m = read_frame->m; |
897 | session->enc_read_frame.payload = session->read_impl.ianacode; |
898 | } |
899 | *frame = &session->enc_read_frame; |
900 | break; |
901 | case SWITCH_STATUS_NOOP: |
902 | session->raw_read_frame.samples = enc_frame->codec->implementation->samples_per_packet; |
903 | session->raw_read_frame.channels = enc_frame->codec->implementation->number_of_channels; |
904 | session->raw_read_frame.timestamp = read_frame->timestamp; |
905 | session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode; |
906 | session->raw_read_frame.m = read_frame->m; |
907 | session->raw_read_frame.ssrc = read_frame->ssrc; |
908 | session->raw_read_frame.seq = read_frame->seq; |
909 | *frame = enc_frame; |
910 | status = SWITCH_STATUS_SUCCESS; |
911 | break; |
912 | case SWITCH_STATUS_NOT_INITALIZED: |
913 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 913, (const char*)(session), SWITCH_LOG_ERROR, "Codec init error!\n"); |
914 | *frame = NULL((void*)0); |
915 | status = SWITCH_STATUS_GENERR; |
916 | break; |
917 | default: |
918 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 918, (const char*)(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n", |
919 | session->read_codec->codec_interface->interface_name); |
920 | *frame = NULL((void*)0); |
921 | status = SWITCH_STATUS_GENERR; |
922 | break; |
923 | } |
924 | } else { |
925 | goto top; |
926 | } |
927 | } |
928 | } |
929 | |
930 | done: |
931 | if (!(*frame)) { |
932 | status = SWITCH_STATUS_FALSE; |
933 | } else { |
934 | if (flag & SFF_CNG) { |
935 | switch_set_flag((*frame), SFF_CNG)((*frame))->flags |= (SFF_CNG); |
936 | } |
937 | if (session->bugs) { |
938 | switch_media_bug_t *bp; |
939 | switch_bool_t ok = SWITCH_TRUE; |
940 | int prune = 0; |
941 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
942 | for (bp = session->bugs; bp; bp = bp->next) { |
943 | ok = SWITCH_TRUE; |
944 | |
945 | if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { |
946 | continue; |
947 | } |
948 | |
949 | if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { |
950 | continue; |
951 | } |
952 | |
953 | if (!switch_channel_test_flag(session->channel, CF_BRIDGED) && switch_core_media_bug_test_flag(bp, SMBF_BRIDGE_REQ)) { |
954 | continue; |
955 | } |
956 | |
957 | if (switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE)) { |
958 | prune++; |
959 | continue; |
960 | } |
961 | |
962 | if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)((bp)->flags & SMBF_READ_PING)) { |
963 | switch_mutex_lock(bp->read_mutex); |
964 | bp->ping_frame = *frame; |
965 | if (bp->callback) { |
966 | if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_PING) == SWITCH_FALSE |
967 | || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL((void*)0)))) { |
968 | ok = SWITCH_FALSE; |
969 | } |
970 | } |
971 | bp->ping_frame = NULL((void*)0);; |
972 | switch_mutex_unlock(bp->read_mutex); |
973 | } |
974 | |
975 | if (ok == SWITCH_FALSE) { |
976 | switch_set_flag(bp, SMBF_PRUNE)(bp)->flags |= (SMBF_PRUNE); |
977 | prune++; |
978 | } |
979 | } |
980 | switch_thread_rwlock_unlock(session->bug_rwlock); |
981 | if (prune) { |
982 | switch_core_media_bug_prune(session); |
983 | } |
984 | } |
985 | } |
986 | |
987 | even_more_done: |
988 | |
989 | if (!*frame || |
990 | (!switch_test_flag(*frame, SFF_PROXY_PACKET)((*frame)->flags & SFF_PROXY_PACKET) && |
991 | (!(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)))) { |
992 | *frame = &runtime.dummy_cng_frame; |
993 | } |
994 | |
995 | switch_mutex_unlock(session->read_codec->mutex); |
996 | switch_mutex_unlock(session->codec_read_mutex); |
997 | |
998 | |
999 | if (status == SWITCH_STATUS_SUCCESS && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { |
1000 | switch_channel_set_callstate(session->channel, CCS_ACTIVE)switch_channel_perform_set_callstate(session->channel, CCS_ACTIVE , "src/switch_core_io.c", (const char *)__func__, 1000); |
1001 | } |
1002 | |
1003 | |
1004 | return status; |
1005 | } |
1006 | |
1007 | static switch_status_t perform_write(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) |
1008 | { |
1009 | switch_io_event_hook_write_frame_t *ptr; |
1010 | switch_status_t status = SWITCH_STATUS_FALSE; |
1011 | |
1012 | |
1013 | if (session->bugs && !(frame->flags & SFF_NOT_AUDIO)) { |
1014 | switch_media_bug_t *bp; |
1015 | switch_bool_t ok = SWITCH_TRUE; |
1016 | int prune = 0; |
1017 | |
1018 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
1019 | |
1020 | for (bp = session->bugs; bp; bp = bp->next) { |
1021 | ok = SWITCH_TRUE; |
1022 | |
1023 | if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { |
1024 | continue; |
1025 | } |
1026 | |
1027 | if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { |
1028 | continue; |
1029 | } |
1030 | if (switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE)) { |
1031 | prune++; |
1032 | continue; |
1033 | } |
1034 | |
1035 | if (bp->ready) { |
1036 | if (switch_test_flag(bp, SMBF_TAP_NATIVE_WRITE)((bp)->flags & SMBF_TAP_NATIVE_WRITE)) { |
1037 | if (bp->callback) { |
1038 | bp->native_write_frame = frame; |
1039 | ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_TAP_NATIVE_WRITE); |
1040 | bp->native_write_frame = NULL((void*)0); |
1041 | } |
1042 | } |
1043 | } |
1044 | |
1045 | if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL((void*)0))) || ok == SWITCH_FALSE) { |
1046 | switch_set_flag(bp, SMBF_PRUNE)(bp)->flags |= (SMBF_PRUNE); |
1047 | prune++; |
1048 | } |
1049 | } |
1050 | switch_thread_rwlock_unlock(session->bug_rwlock); |
1051 | |
1052 | if (prune) { |
1053 | switch_core_media_bug_prune(session); |
1054 | } |
1055 | } |
1056 | |
1057 | |
1058 | if (session->endpoint_interface->io_routines->write_frame) { |
1059 | if ((status = session->endpoint_interface->io_routines->write_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { |
1060 | for (ptr = session->event_hooks.write_frame; ptr; ptr = ptr->next) { |
1061 | if ((status = ptr->write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { |
1062 | break; |
1063 | } |
1064 | } |
1065 | } |
1066 | } |
1067 | |
1068 | return status; |
1069 | } |
1070 | |
1071 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, |
1072 | int stream_id) |
1073 | { |
1074 | |
1075 | switch_status_t status = SWITCH_STATUS_FALSE; |
1076 | switch_frame_t *enc_frame = NULL((void*)0), *write_frame = frame; |
1077 | 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; |
1078 | int did_write_resample = 0; |
1079 | |
1080 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_io.c", 1080, __PRETTY_FUNCTION__)); |
1081 | switch_assert(frame != NULL)((frame != ((void*)0)) ? (void) (0) : __assert_fail ("frame != ((void*)0)" , "src/switch_core_io.c", 1081, __PRETTY_FUNCTION__)); |
1082 | |
1083 | if (!switch_channel_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_FALSE )) { |
1084 | return SWITCH_STATUS_FALSE; |
1085 | } |
1086 | |
1087 | if (switch_mutex_trylock(session->codec_write_mutex) == SWITCH_STATUS_SUCCESS) { |
1088 | switch_mutex_unlock(session->codec_write_mutex); |
1089 | } else { |
1090 | return SWITCH_STATUS_SUCCESS; |
1091 | } |
1092 | |
1093 | if (switch_test_flag(frame, SFF_CNG)((frame)->flags & SFF_CNG)) { |
1094 | if (switch_channel_test_flag(session->channel, CF_ACCEPT_CNG)) { |
1095 | pass_cng = 1; |
1096 | } else { |
1097 | return SWITCH_STATUS_SUCCESS; |
1098 | } |
1099 | } |
1100 | |
1101 | if (switch_channel_test_flag(session->channel, CF_AUDIO_PAUSE)) { |
1102 | return SWITCH_STATUS_SUCCESS; |
1103 | } |
1104 | |
1105 | if (!(session->write_codec && switch_core_codec_ready(session->write_codec)) && !pass_cng) { |
1106 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1106, (const char*)(session), SWITCH_LOG_ERROR, "%s has no write codec.\n", switch_channel_get_name(session->channel)); |
1107 | switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_io.c" , (const char *)__func__, 1107, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ); |
1108 | return SWITCH_STATUS_FALSE; |
1109 | } |
1110 | |
1111 | if (switch_channel_test_flag(session->channel, CF_HOLD)) { |
1112 | return SWITCH_STATUS_SUCCESS; |
1113 | } |
1114 | |
1115 | if (switch_test_flag(frame, SFF_PROXY_PACKET)((frame)->flags & SFF_PROXY_PACKET) || pass_cng) { |
1116 | /* Fast PASS! */ |
1117 | switch_mutex_lock(session->codec_write_mutex); |
1118 | status = perform_write(session, frame, flag, stream_id); |
1119 | switch_mutex_unlock(session->codec_write_mutex); |
1120 | return status; |
1121 | } |
1122 | |
1123 | switch_mutex_lock(session->codec_write_mutex); |
1124 | |
1125 | if (!(frame->codec && frame->codec->implementation)) { |
1126 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1126, (const char*)(session), SWITCH_LOG_ERROR, "%s has received a bad frame with no codec!\n", |
1127 | switch_channel_get_name(session->channel)); |
1128 | switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(session->channel, "src/switch_core_io.c" , (const char *)__func__, 1128, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ); |
1129 | switch_mutex_unlock(session->codec_write_mutex); |
1130 | return SWITCH_STATUS_FALSE; |
1131 | } |
1132 | |
1133 | switch_assert(frame->codec != NULL)((frame->codec != ((void*)0)) ? (void) (0) : __assert_fail ("frame->codec != ((void*)0)", "src/switch_core_io.c", 1133 , __PRETTY_FUNCTION__)); |
1134 | switch_assert(frame->codec->implementation != NULL)((frame->codec->implementation != ((void*)0)) ? (void) ( 0) : __assert_fail ("frame->codec->implementation != ((void*)0)" , "src/switch_core_io.c", 1134, __PRETTY_FUNCTION__)); |
1135 | |
1136 | if (!(switch_core_codec_ready(session->write_codec) && frame->codec) || |
1137 | !switch_channel_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_FALSE ) || !switch_channel_media_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_TRUE )) { |
1138 | switch_mutex_unlock(session->codec_write_mutex); |
1139 | return SWITCH_STATUS_FALSE; |
1140 | } |
1141 | |
1142 | switch_mutex_lock(session->write_codec->mutex); |
1143 | switch_mutex_lock(frame->codec->mutex); |
1144 | |
1145 | if (!(switch_core_codec_ready(session->write_codec) && switch_core_codec_ready(frame->codec))) goto error; |
1146 | |
1147 | if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) { |
1148 | if (session->write_impl.codec_id == frame->codec->implementation->codec_id || |
1149 | session->write_impl.microseconds_per_packet != frame->codec->implementation->microseconds_per_packet) { |
1150 | ptime_mismatch = TRUE(!0); |
1151 | if ((switch_test_flag(frame->codec, SWITCH_CODEC_FLAG_PASSTHROUGH)((frame->codec)->flags & SWITCH_CODEC_FLAG_PASSTHROUGH ) || switch_test_flag(session->read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)((session->read_codec)->flags & SWITCH_CODEC_FLAG_PASSTHROUGH )) || |
1152 | switch_channel_test_flag(session->channel, CF_PASSTHRU_PTIME_MISMATCH)) { |
1153 | status = perform_write(session, frame, flags, stream_id); |
1154 | goto error; |
1155 | } |
1156 | } |
1157 | need_codec = TRUE(!0); |
1158 | } |
1159 | |
1160 | if (session->write_codec && !frame->codec) { |
1161 | need_codec = TRUE(!0); |
1162 | } |
1163 | |
1164 | if (session->bugs && !need_codec && !switch_test_flag(session, SSF_MEDIA_BUG_TAP_ONLY)((session)->flags & SSF_MEDIA_BUG_TAP_ONLY)) { |
1165 | do_bugs = TRUE(!0); |
1166 | need_codec = TRUE(!0); |
1167 | } |
1168 | |
1169 | if (frame->codec->implementation->actual_samples_per_second != session->write_impl.actual_samples_per_second) { |
1170 | need_codec = TRUE(!0); |
1171 | do_resample = TRUE(!0); |
1172 | } |
1173 | |
1174 | |
1175 | if ((frame->flags & SFF_NOT_AUDIO)) { |
1176 | do_resample = 0; |
1177 | do_bugs = 0; |
1178 | need_codec = 0; |
1179 | } |
1180 | |
1181 | if (switch_test_flag(session, SSF_WRITE_TRANSCODE)((session)->flags & SSF_WRITE_TRANSCODE) && !need_codec && switch_core_codec_ready(session->write_codec)) { |
1182 | switch_core_session_t *other_session; |
1183 | const char *uuid = switch_channel_get_partner_uuid(switch_core_session_get_channel(session)); |
1184 | |
1185 | if (uuid && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_core_io.c" , (const char *)__func__, 1185))) { |
1186 | switch_set_flag(other_session, SSF_READ_CODEC_RESET)(other_session)->flags |= (SSF_READ_CODEC_RESET); |
1187 | switch_set_flag(other_session, SSF_READ_CODEC_RESET)(other_session)->flags |= (SSF_READ_CODEC_RESET); |
1188 | switch_set_flag(other_session, SSF_WRITE_CODEC_RESET)(other_session)->flags |= (SSF_WRITE_CODEC_RESET); |
1189 | switch_core_session_rwunlock(other_session); |
1190 | } |
1191 | |
1192 | switch_clear_flag(session, SSF_WRITE_TRANSCODE)(session)->flags &= ~(SSF_WRITE_TRANSCODE); |
1193 | } |
1194 | |
1195 | |
1196 | if (switch_test_flag(session, SSF_WRITE_CODEC_RESET)((session)->flags & SSF_WRITE_CODEC_RESET)) { |
1197 | switch_core_codec_reset(session->write_codec); |
1198 | switch_clear_flag(session, SSF_WRITE_CODEC_RESET)(session)->flags &= ~(SSF_WRITE_CODEC_RESET); |
1199 | } |
1200 | |
1201 | if (!need_codec) { |
1202 | do_write = TRUE(!0); |
1203 | write_frame = frame; |
1204 | goto done; |
1205 | } |
1206 | |
1207 | if (!switch_test_flag(session, SSF_WARN_TRANSCODE)((session)->flags & SSF_WARN_TRANSCODE)) { |
1208 | switch_core_session_message_t msg = { 0 }; |
1209 | |
1210 | msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY; |
1211 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 1211); |
1212 | switch_set_flag(session, SSF_WARN_TRANSCODE)(session)->flags |= (SSF_WARN_TRANSCODE); |
1213 | } |
1214 | |
1215 | if (frame->codec) { |
1216 | session->raw_write_frame.datalen = session->raw_write_frame.buflen; |
1217 | frame->codec->cur_frame = frame; |
1218 | session->write_codec->cur_frame = frame; |
1219 | status = switch_core_codec_decode(frame->codec, |
1220 | session->write_codec, |
1221 | frame->data, |
1222 | frame->datalen, |
1223 | session->write_impl.actual_samples_per_second, |
1224 | session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags); |
1225 | frame->codec->cur_frame = NULL((void*)0); |
1226 | session->write_codec->cur_frame = NULL((void*)0); |
1227 | if (do_resample && status == SWITCH_STATUS_SUCCESS) { |
1228 | status = SWITCH_STATUS_RESAMPLE; |
1229 | } |
1230 | |
1231 | /* mux or demux to match */ |
1232 | if (session->write_impl.number_of_channels != frame->codec->implementation->number_of_channels) { |
1233 | uint32_t rlen = session->raw_write_frame.datalen / 2 / frame->codec->implementation->number_of_channels; |
1234 | switch_mux_channels((int16_t *) session->raw_write_frame.data, rlen, |
1235 | frame->codec->implementation->number_of_channels, session->write_impl.number_of_channels); |
1236 | session->raw_write_frame.datalen = rlen * 2 * session->write_impl.number_of_channels; |
1237 | } |
1238 | |
1239 | switch (status) { |
1240 | case SWITCH_STATUS_RESAMPLE: |
1241 | resample++; |
1242 | write_frame = &session->raw_write_frame; |
1243 | write_frame->rate = frame->codec->implementation->actual_samples_per_second; |
1244 | if (!session->write_resampler) { |
1245 | switch_mutex_lock(session->resample_mutex); |
1246 | status = switch_resample_create(&session->write_resampler,switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1249) |
1247 | frame->codec->implementation->actual_samples_per_second,switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1249) |
1248 | session->write_impl.actual_samples_per_second,switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1249) |
1249 | session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, session->write_impl.number_of_channels)switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1249); |
1250 | |
1251 | |
1252 | switch_mutex_unlock(session->resample_mutex); |
1253 | if (status != SWITCH_STATUS_SUCCESS) { |
1254 | goto done; |
1255 | } else { |
1256 | switch_core_session_message_t msg = { 0 }; |
1257 | msg.numeric_arg = 1; |
1258 | msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT; |
1259 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 1259); |
1260 | |
1261 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1261, (const char*)(session), SWITCH_LOG_NOTICE, "Activating write resampler\n"); |
1262 | } |
1263 | } |
1264 | break; |
1265 | case SWITCH_STATUS_SUCCESS: |
1266 | session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t) / session->write_impl.number_of_channels; |
1267 | session->raw_write_frame.channels = session->write_impl.number_of_channels; |
1268 | session->raw_write_frame.timestamp = frame->timestamp; |
1269 | session->raw_write_frame.rate = frame->rate; |
1270 | session->raw_write_frame.m = frame->m; |
1271 | session->raw_write_frame.ssrc = frame->ssrc; |
1272 | session->raw_write_frame.seq = frame->seq; |
1273 | session->raw_write_frame.payload = frame->payload; |
1274 | session->raw_write_frame.flags = 0; |
1275 | if (switch_test_flag(frame, SFF_PLC)((frame)->flags & SFF_PLC)) { |
1276 | session->raw_write_frame.flags |= SFF_PLC; |
1277 | } |
1278 | |
1279 | write_frame = &session->raw_write_frame; |
1280 | break; |
1281 | case SWITCH_STATUS_BREAK: |
1282 | status = SWITCH_STATUS_SUCCESS; |
1283 | goto error; |
1284 | case SWITCH_STATUS_NOOP: |
1285 | if (session->write_resampler) { |
1286 | switch_mutex_lock(session->resample_mutex); |
1287 | switch_resample_destroy(&session->write_resampler); |
1288 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1288, (const char*)(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n"); |
1289 | switch_mutex_unlock(session->resample_mutex); |
1290 | |
1291 | { |
1292 | switch_core_session_message_t msg = { 0 }; |
1293 | msg.numeric_arg = 0; |
1294 | msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT; |
1295 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 1295); |
1296 | } |
1297 | |
1298 | } |
1299 | write_frame = frame; |
1300 | status = SWITCH_STATUS_SUCCESS; |
1301 | break; |
1302 | default: |
1303 | |
1304 | if (status == SWITCH_STATUS_NOT_INITALIZED) { |
1305 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1305, (const char*)(session), SWITCH_LOG_ERROR, "Codec init error!\n"); |
1306 | goto error; |
1307 | } |
1308 | if (ptime_mismatch && status != SWITCH_STATUS_GENERR) { |
1309 | status = perform_write(session, frame, flags, stream_id); |
Value stored to 'status' is never read | |
1310 | status = SWITCH_STATUS_SUCCESS; |
1311 | goto error; |
1312 | } |
1313 | |
1314 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1314, (const char*)(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n", |
1315 | frame->codec->codec_interface->interface_name); |
1316 | goto error; |
1317 | } |
1318 | } |
1319 | |
1320 | |
1321 | |
1322 | if (session->write_resampler) { |
1323 | short *data = write_frame->data; |
1324 | |
1325 | switch_mutex_lock(session->resample_mutex); |
1326 | if (session->write_resampler) { |
1327 | |
1328 | switch_resample_process(session->write_resampler, data, write_frame->datalen / 2 / session->write_resampler->channels); |
1329 | |
1330 | memcpy(data, session->write_resampler->to, session->write_resampler->to_len * 2 * session->write_resampler->channels); |
1331 | |
1332 | write_frame->samples = session->write_resampler->to_len; |
1333 | write_frame->channels = session->write_resampler->channels; |
1334 | write_frame->datalen = write_frame->samples * 2 * session->write_resampler->channels; |
1335 | |
1336 | write_frame->rate = session->write_resampler->to_rate; |
1337 | |
1338 | did_write_resample = 1; |
1339 | } |
1340 | switch_mutex_unlock(session->resample_mutex); |
1341 | } |
1342 | |
1343 | |
1344 | |
1345 | if (session->bugs) { |
1346 | switch_media_bug_t *bp; |
1347 | int prune = 0; |
1348 | |
1349 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
1350 | for (bp = session->bugs; bp; bp = bp->next) { |
1351 | switch_bool_t ok = SWITCH_TRUE; |
1352 | |
1353 | if (!bp->ready) { |
1354 | continue; |
1355 | } |
1356 | |
1357 | if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { |
1358 | continue; |
1359 | } |
1360 | |
1361 | if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { |
1362 | continue; |
1363 | } |
1364 | |
1365 | if (switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE)) { |
1366 | prune++; |
1367 | continue; |
1368 | } |
1369 | |
1370 | if (switch_test_flag(bp, SMBF_WRITE_STREAM)((bp)->flags & SMBF_WRITE_STREAM)) { |
1371 | switch_mutex_lock(bp->write_mutex); |
1372 | switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen); |
1373 | switch_mutex_unlock(bp->write_mutex); |
1374 | |
1375 | if (bp->callback) { |
1376 | ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE); |
1377 | } |
1378 | } |
1379 | |
1380 | if (switch_test_flag(bp, SMBF_WRITE_REPLACE)((bp)->flags & SMBF_WRITE_REPLACE)) { |
1381 | do_bugs = 0; |
1382 | if (bp->callback) { |
1383 | bp->write_replace_frame_in = write_frame; |
1384 | bp->write_replace_frame_out = write_frame; |
1385 | if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) { |
1386 | write_frame = bp->write_replace_frame_out; |
1387 | } |
1388 | } |
1389 | } |
1390 | |
1391 | if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL((void*)0))) { |
1392 | ok = SWITCH_FALSE; |
1393 | } |
1394 | |
1395 | |
1396 | if (ok == SWITCH_FALSE) { |
1397 | switch_set_flag(bp, SMBF_PRUNE)(bp)->flags |= (SMBF_PRUNE); |
1398 | prune++; |
1399 | } |
1400 | } |
1401 | switch_thread_rwlock_unlock(session->bug_rwlock); |
1402 | if (prune) { |
1403 | switch_core_media_bug_prune(session); |
1404 | } |
1405 | } |
1406 | |
1407 | if (do_bugs) { |
1408 | do_write = TRUE(!0); |
1409 | write_frame = frame; |
1410 | goto done; |
1411 | } |
1412 | |
1413 | if (session->write_codec) { |
1414 | if (!ptime_mismatch && write_frame->codec && write_frame->codec->implementation && |
1415 | write_frame->codec->implementation->decoded_bytes_per_packet == session->write_impl.decoded_bytes_per_packet) { |
1416 | perfect = TRUE(!0); |
1417 | } |
1418 | |
1419 | |
1420 | |
1421 | if (perfect) { |
1422 | |
1423 | if (write_frame->datalen < session->write_impl.decoded_bytes_per_packet) { |
1424 | memset(write_frame->data, 255, session->write_impl.decoded_bytes_per_packet - write_frame->datalen); |
1425 | write_frame->datalen = session->write_impl.decoded_bytes_per_packet; |
1426 | } |
1427 | |
1428 | enc_frame = write_frame; |
1429 | session->enc_write_frame.datalen = session->enc_write_frame.buflen; |
1430 | session->write_codec->cur_frame = frame; |
1431 | frame->codec->cur_frame = frame; |
1432 | switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((enc_frame->datalen <= 8192) ? (void) (0) : __assert_fail ("enc_frame->datalen <= 8192", "src/switch_core_io.c", 1432, __PRETTY_FUNCTION__)); |
1433 | switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((session->enc_read_frame.datalen <= 8192) ? (void) (0) : __assert_fail ("session->enc_read_frame.datalen <= 8192" , "src/switch_core_io.c", 1433, __PRETTY_FUNCTION__)); |
1434 | status = switch_core_codec_encode(session->write_codec, |
1435 | frame->codec, |
1436 | enc_frame->data, |
1437 | enc_frame->datalen, |
1438 | session->write_impl.actual_samples_per_second, |
1439 | session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); |
1440 | |
1441 | switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((session->enc_read_frame.datalen <= 8192) ? (void) (0) : __assert_fail ("session->enc_read_frame.datalen <= 8192" , "src/switch_core_io.c", 1441, __PRETTY_FUNCTION__)); |
1442 | |
1443 | session->write_codec->cur_frame = NULL((void*)0); |
1444 | frame->codec->cur_frame = NULL((void*)0); |
1445 | switch (status) { |
1446 | case SWITCH_STATUS_RESAMPLE: |
1447 | resample++; |
1448 | /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 2\n"); */ |
1449 | case SWITCH_STATUS_SUCCESS: |
1450 | session->enc_write_frame.codec = session->write_codec; |
1451 | session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels; |
1452 | session->enc_write_frame.channels = session->write_impl.number_of_channels; |
1453 | if (frame->codec->implementation->samples_per_packet != session->write_impl.samples_per_packet) { |
1454 | session->enc_write_frame.timestamp = 0; |
1455 | } else { |
1456 | session->enc_write_frame.timestamp = frame->timestamp; |
1457 | } |
1458 | session->enc_write_frame.payload = session->write_impl.ianacode; |
1459 | session->enc_write_frame.m = frame->m; |
1460 | session->enc_write_frame.ssrc = frame->ssrc; |
1461 | session->enc_write_frame.seq = frame->seq; |
1462 | session->enc_write_frame.flags = 0; |
1463 | write_frame = &session->enc_write_frame; |
1464 | break; |
1465 | case SWITCH_STATUS_NOOP: |
1466 | enc_frame->codec = session->write_codec; |
1467 | enc_frame->samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels; |
1468 | enc_frame->channels = session->write_impl.number_of_channels; |
1469 | enc_frame->timestamp = frame->timestamp; |
1470 | enc_frame->m = frame->m; |
1471 | enc_frame->seq = frame->seq; |
1472 | enc_frame->ssrc = frame->ssrc; |
1473 | enc_frame->payload = enc_frame->codec->implementation->ianacode; |
1474 | write_frame = enc_frame; |
1475 | status = SWITCH_STATUS_SUCCESS; |
1476 | break; |
1477 | case SWITCH_STATUS_NOT_INITALIZED: |
1478 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1478, (const char*)(session), SWITCH_LOG_ERROR, "Codec init error!\n"); |
1479 | write_frame = NULL((void*)0); |
1480 | goto error; |
1481 | default: |
1482 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1482, (const char*)(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n", |
1483 | session->read_codec->codec_interface->interface_name); |
1484 | write_frame = NULL((void*)0); |
1485 | goto error; |
1486 | } |
1487 | if (flag & SFF_CNG) { |
1488 | switch_set_flag(write_frame, SFF_CNG)(write_frame)->flags |= (SFF_CNG); |
1489 | } |
1490 | |
1491 | status = perform_write(session, write_frame, flags, stream_id); |
1492 | goto error; |
1493 | } else { |
1494 | if (!session->raw_write_buffer) { |
1495 | switch_size_t bytes_per_packet = session->write_impl.decoded_bytes_per_packet; |
1496 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1496, (const char*)(session), SWITCH_LOG_DEBUG, |
1497 | "Engaging Write Buffer at %u bytes to accommodate %u->%u\n", |
1498 | (uint32_t) bytes_per_packet, write_frame->datalen, session->write_impl.decoded_bytes_per_packet); |
1499 | if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer, |
1500 | bytes_per_packet * SWITCH_BUFFER_BLOCK_FRAMES25, |
1501 | bytes_per_packet * SWITCH_BUFFER_START_FRAMES50, 0)) != SWITCH_STATUS_SUCCESS) { |
1502 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1502, (const char*)(session), SWITCH_LOG_ERROR, "Write Buffer Failed!\n"); |
1503 | goto error; |
1504 | } |
1505 | |
1506 | /* Need to retrain the recording data */ |
1507 | switch_core_media_bug_flush_all(session); |
1508 | } |
1509 | |
1510 | if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) { |
1511 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1511, (const char*)(session), SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen); |
1512 | status = SWITCH_STATUS_MEMERR; |
1513 | goto error; |
1514 | } |
1515 | |
1516 | status = SWITCH_STATUS_SUCCESS; |
1517 | |
1518 | while (switch_buffer_inuse(session->raw_write_buffer) >= session->write_impl.decoded_bytes_per_packet) { |
1519 | int rate; |
1520 | |
1521 | if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) >= CS_HANGUP ) || !session->raw_write_buffer) { |
1522 | goto error; |
1523 | } |
1524 | if ((session->raw_write_frame.datalen = (uint32_t) |
1525 | switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, session->write_impl.decoded_bytes_per_packet)) == 0) { |
1526 | goto error; |
1527 | } |
1528 | |
1529 | enc_frame = &session->raw_write_frame; |
1530 | session->raw_write_frame.rate = session->write_impl.actual_samples_per_second; |
1531 | session->enc_write_frame.datalen = session->enc_write_frame.buflen; |
1532 | session->enc_write_frame.timestamp = 0; |
1533 | |
1534 | |
1535 | if (frame->codec && frame->codec->implementation && switch_core_codec_ready(frame->codec)) { |
1536 | rate = frame->codec->implementation->actual_samples_per_second; |
1537 | } else { |
1538 | rate = session->write_impl.actual_samples_per_second; |
1539 | } |
1540 | |
1541 | session->write_codec->cur_frame = frame; |
1542 | frame->codec->cur_frame = frame; |
1543 | switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((enc_frame->datalen <= 8192) ? (void) (0) : __assert_fail ("enc_frame->datalen <= 8192", "src/switch_core_io.c", 1543, __PRETTY_FUNCTION__)); |
1544 | switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((session->enc_read_frame.datalen <= 8192) ? (void) (0) : __assert_fail ("session->enc_read_frame.datalen <= 8192" , "src/switch_core_io.c", 1544, __PRETTY_FUNCTION__)); |
1545 | status = switch_core_codec_encode(session->write_codec, |
1546 | frame->codec, |
1547 | enc_frame->data, |
1548 | enc_frame->datalen, |
1549 | rate, |
1550 | session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); |
1551 | |
1552 | switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((session->enc_read_frame.datalen <= 8192) ? (void) (0) : __assert_fail ("session->enc_read_frame.datalen <= 8192" , "src/switch_core_io.c", 1552, __PRETTY_FUNCTION__)); |
1553 | |
1554 | session->write_codec->cur_frame = NULL((void*)0); |
1555 | frame->codec->cur_frame = NULL((void*)0); |
1556 | switch (status) { |
1557 | case SWITCH_STATUS_RESAMPLE: |
1558 | resample++; |
1559 | session->enc_write_frame.codec = session->write_codec; |
1560 | session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels; |
1561 | session->enc_write_frame.channels = session->write_impl.number_of_channels; |
1562 | session->enc_write_frame.m = frame->m; |
1563 | session->enc_write_frame.ssrc = frame->ssrc; |
1564 | session->enc_write_frame.payload = session->write_impl.ianacode; |
1565 | write_frame = &session->enc_write_frame; |
1566 | if (!session->write_resampler) { |
1567 | switch_mutex_lock(session->resample_mutex); |
1568 | if (!session->write_resampler) { |
1569 | status = switch_resample_create(&session->write_resampler,switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1573) |
1570 | frame->codec->implementation->actual_samples_per_second,switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1573) |
1571 | session->write_impl.actual_samples_per_second,switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1573) |
1572 | session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY,switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1573) |
1573 | session->write_impl.number_of_channels)switch_resample_perform_create(&session->write_resampler , frame->codec->implementation->actual_samples_per_second , session->write_impl.actual_samples_per_second, session-> write_impl.decoded_bytes_per_packet, 2, session->write_impl .number_of_channels, "src/switch_core_io.c", (const char *)__func__ , 1573); |
1574 | } |
1575 | switch_mutex_unlock(session->resample_mutex); |
1576 | |
1577 | |
1578 | |
1579 | if (status != SWITCH_STATUS_SUCCESS) { |
1580 | goto done; |
1581 | } else { |
1582 | switch_core_session_message_t msg = { 0 }; |
1583 | msg.numeric_arg = 1; |
1584 | msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT; |
1585 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 1585); |
1586 | |
1587 | |
1588 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1588, (const char*)(session), SWITCH_LOG_NOTICE, "Activating write resampler\n"); |
1589 | } |
1590 | } |
1591 | break; |
1592 | case SWITCH_STATUS_SUCCESS: |
1593 | session->enc_write_frame.codec = session->write_codec; |
1594 | session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels; |
1595 | session->enc_write_frame.channels = session->write_impl.number_of_channels; |
1596 | session->enc_write_frame.m = frame->m; |
1597 | session->enc_write_frame.ssrc = frame->ssrc; |
1598 | session->enc_write_frame.payload = session->write_impl.ianacode; |
1599 | session->enc_write_frame.flags = 0; |
1600 | write_frame = &session->enc_write_frame; |
1601 | break; |
1602 | case SWITCH_STATUS_NOOP: |
1603 | if (session->write_resampler) { |
1604 | switch_core_session_message_t msg = { 0 }; |
1605 | int ok = 0; |
1606 | |
1607 | switch_mutex_lock(session->resample_mutex); |
1608 | if (session->write_resampler) { |
1609 | switch_resample_destroy(&session->write_resampler); |
1610 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1610, (const char*)(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n"); |
1611 | ok = 1; |
1612 | } |
1613 | switch_mutex_unlock(session->resample_mutex); |
1614 | |
1615 | if (ok) { |
1616 | msg.numeric_arg = 0; |
1617 | msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT; |
1618 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_core_io.c", (const char *)__func__, 1618); |
1619 | } |
1620 | |
1621 | } |
1622 | enc_frame->codec = session->write_codec; |
1623 | enc_frame->samples = enc_frame->datalen / sizeof(int16_t) / session->read_impl.number_of_channels; |
1624 | enc_frame->channels = session->read_impl.number_of_channels; |
1625 | enc_frame->m = frame->m; |
1626 | enc_frame->ssrc = frame->ssrc; |
1627 | enc_frame->payload = enc_frame->codec->implementation->ianacode; |
1628 | write_frame = enc_frame; |
1629 | status = SWITCH_STATUS_SUCCESS; |
1630 | break; |
1631 | case SWITCH_STATUS_NOT_INITALIZED: |
1632 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1632, (const char*)(session), SWITCH_LOG_ERROR, "Codec init error!\n"); |
1633 | write_frame = NULL((void*)0); |
1634 | goto error; |
1635 | default: |
1636 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1636, (const char*)(session), SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n", |
1637 | session->read_codec->codec_interface->interface_name, status); |
1638 | write_frame = NULL((void*)0); |
1639 | goto error; |
1640 | } |
1641 | |
1642 | if (!did_write_resample && session->read_resampler) { |
1643 | short *data = write_frame->data; |
1644 | switch_mutex_lock(session->resample_mutex); |
1645 | if (session->read_resampler) { |
1646 | switch_resample_process(session->read_resampler, data, write_frame->datalen / 2 / session->read_resampler->channels); |
1647 | memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2 * session->read_resampler->channels); |
1648 | write_frame->samples = session->read_resampler->to_len; |
1649 | write_frame->channels = session->read_resampler->channels; |
1650 | write_frame->datalen = session->read_resampler->to_len * 2 * session->read_resampler->channels; |
1651 | write_frame->rate = session->read_resampler->to_rate; |
1652 | } |
1653 | switch_mutex_unlock(session->resample_mutex); |
1654 | |
1655 | } |
1656 | |
1657 | if (flag & SFF_CNG) { |
1658 | switch_set_flag(write_frame, SFF_CNG)(write_frame)->flags |= (SFF_CNG); |
1659 | } |
1660 | |
1661 | if (ptime_mismatch || resample) { |
1662 | write_frame->timestamp = 0; |
1663 | } |
1664 | |
1665 | if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { |
1666 | break; |
1667 | } |
1668 | |
1669 | } |
1670 | |
1671 | goto error; |
1672 | } |
1673 | } |
1674 | |
1675 | |
1676 | |
1677 | |
1678 | |
1679 | done: |
1680 | |
1681 | if (ptime_mismatch || resample) { |
1682 | write_frame->timestamp = 0; |
1683 | } |
1684 | |
1685 | if (do_write) { |
1686 | status = perform_write(session, write_frame, flags, stream_id); |
1687 | } |
1688 | |
1689 | error: |
1690 | |
1691 | switch_mutex_unlock(session->write_codec->mutex); |
1692 | switch_mutex_unlock(frame->codec->mutex); |
1693 | switch_mutex_unlock(session->codec_write_mutex); |
1694 | |
1695 | return status; |
1696 | } |
1697 | |
1698 | static char *SIG_NAMES[] = { |
1699 | "NONE", |
1700 | "KILL", |
1701 | "XFER", |
1702 | "BREAK", |
1703 | NULL((void*)0) |
1704 | }; |
1705 | |
1706 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_perform_kill_channel(switch_core_session_t *session, |
1707 | const char *file, const char *func, int line, switch_signal_t sig) |
1708 | { |
1709 | switch_io_event_hook_kill_channel_t *ptr; |
1710 | switch_status_t status = SWITCH_STATUS_FALSE; |
1711 | |
1712 | switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "Send signal %s [%s]\n", |
1713 | switch_channel_get_name(session->channel), SIG_NAMES[sig]); |
1714 | |
1715 | if (session->endpoint_interface->io_routines->kill_channel) { |
1716 | if ((status = session->endpoint_interface->io_routines->kill_channel(session, sig)) == SWITCH_STATUS_SUCCESS) { |
1717 | for (ptr = session->event_hooks.kill_channel; ptr; ptr = ptr->next) { |
1718 | if ((status = ptr->kill_channel(session, sig)) != SWITCH_STATUS_SUCCESS) { |
1719 | break; |
1720 | } |
1721 | } |
1722 | } |
1723 | } |
1724 | return status; |
1725 | } |
1726 | |
1727 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_recv_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) |
1728 | { |
1729 | switch_io_event_hook_recv_dtmf_t *ptr; |
1730 | switch_status_t status; |
1731 | switch_dtmf_t new_dtmf; |
1732 | int fed = 0; |
1733 | |
1734 | if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) >= CS_HANGUP )) { |
1735 | return SWITCH_STATUS_FALSE; |
1736 | } |
1737 | |
1738 | if (switch_test_flag(dtmf, DTMF_FLAG_SENSITIVE)((dtmf)->flags & DTMF_FLAG_SENSITIVE)) { |
1739 | return SWITCH_STATUS_SUCCESS; |
1740 | } |
1741 | |
1742 | switch_assert(dtmf)((dtmf) ? (void) (0) : __assert_fail ("dtmf", "src/switch_core_io.c" , 1742, __PRETTY_FUNCTION__)); |
1743 | |
1744 | new_dtmf = *dtmf; |
1745 | |
1746 | if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) { |
1747 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1747, (const char*)(session), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", |
1748 | switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); |
1749 | new_dtmf.duration = switch_core_max_dtmf_duration(0); |
1750 | } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) { |
1751 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1751, (const char*)(session), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", |
1752 | switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); |
1753 | new_dtmf.duration = switch_core_min_dtmf_duration(0); |
1754 | } else if (!new_dtmf.duration) { |
1755 | new_dtmf.duration = switch_core_default_dtmf_duration(0); |
1756 | } |
1757 | |
1758 | if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)((dtmf)->flags & DTMF_FLAG_SKIP_PROCESS)) { |
1759 | if (session->dmachine[0]) { |
1760 | char str[2] = { dtmf->digit, '\0' }; |
1761 | switch_ivr_dmachine_feed(session->dmachine[0], str, NULL((void*)0)); |
1762 | fed = 1; |
1763 | } |
1764 | |
1765 | for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) { |
1766 | if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) { |
1767 | return status; |
1768 | } |
1769 | } |
1770 | } |
1771 | |
1772 | return fed ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS; |
1773 | } |
1774 | |
1775 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) |
1776 | { |
1777 | switch_io_event_hook_send_dtmf_t *ptr; |
1778 | switch_status_t status = SWITCH_STATUS_FALSE; |
1779 | switch_dtmf_t new_dtmf; |
1780 | |
1781 | if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) >= CS_HANGUP )) { |
1782 | return SWITCH_STATUS_FALSE; |
1783 | } |
1784 | |
1785 | if (switch_test_flag(dtmf, DTMF_FLAG_SENSITIVE)((dtmf)->flags & DTMF_FLAG_SENSITIVE)) { |
1786 | return SWITCH_STATUS_SUCCESS; |
1787 | } |
1788 | |
1789 | if (switch_channel_test_flag(session->channel, CF_DROP_DTMF)) { |
1790 | const char *file = switch_channel_get_variable_dup(session->channel, "drop_dtmf_masking_file", SWITCH_FALSE, -1); |
1791 | const char *digits; |
1792 | |
1793 | if (!zstr(file)_zstr(file)) { |
1794 | switch_ivr_broadcast(switch_core_session_get_uuid(session), file, SMF_ECHO_ALEG); |
1795 | } |
1796 | |
1797 | if ((digits = switch_channel_get_variable_dup(session->channel, "drop_dtmf_masking_digits", SWITCH_FALSE, -1)) && !zstr(digits)_zstr(digits)) { |
1798 | const char *p; |
1799 | switch_dtmf_t x_dtmf = { 0, switch_core_default_dtmf_duration(0), DTMF_FLAG_SKIP_PROCESS, 0}; |
1800 | |
1801 | switch_channel_clear_flag(session->channel, CF_DROP_DTMF); |
1802 | for(p = digits; p && *p; p++) { |
1803 | if (is_dtmf(*p)((*p > 47 && *p < 58) || (*p > 64 && *p < 69) || (*p > 96 && *p < 101) || *p == 35 || *p == 42 || *p == 87 || *p == 119 || *p == 70 || *p == 102 )) { |
1804 | x_dtmf.digit = *p; |
1805 | switch_core_session_send_dtmf(session, &x_dtmf); |
1806 | } |
1807 | } |
1808 | switch_channel_set_flag(session->channel, CF_DROP_DTMF)switch_channel_set_flag_value(session->channel, CF_DROP_DTMF , 1); |
1809 | } |
1810 | |
1811 | return SWITCH_STATUS_SUCCESS; |
1812 | } |
1813 | |
1814 | switch_assert(dtmf)((dtmf) ? (void) (0) : __assert_fail ("dtmf", "src/switch_core_io.c" , 1814, __PRETTY_FUNCTION__)); |
1815 | |
1816 | new_dtmf = *dtmf; |
1817 | |
1818 | if (new_dtmf.digit != 'w' && new_dtmf.digit != 'W') { |
1819 | if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) { |
1820 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1820, (const char*)(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", |
1821 | switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); |
1822 | new_dtmf.duration = switch_core_max_dtmf_duration(0); |
1823 | } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) { |
1824 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1824, (const char*)(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", |
1825 | switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); |
1826 | new_dtmf.duration = switch_core_min_dtmf_duration(0); |
1827 | } |
1828 | } |
1829 | |
1830 | if (!new_dtmf.duration) { |
1831 | new_dtmf.duration = switch_core_default_dtmf_duration(0); |
1832 | } |
1833 | |
1834 | if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)((dtmf)->flags & DTMF_FLAG_SKIP_PROCESS)) { |
1835 | for (ptr = session->event_hooks.send_dtmf; ptr; ptr = ptr->next) { |
1836 | if ((status = ptr->send_dtmf(session, dtmf, SWITCH_DTMF_SEND)) != SWITCH_STATUS_SUCCESS) { |
1837 | return SWITCH_STATUS_SUCCESS; |
1838 | } |
1839 | } |
1840 | if (session->dmachine[1]) { |
1841 | char str[2] = { new_dtmf.digit, '\0' }; |
1842 | switch_ivr_dmachine_feed(session->dmachine[1], str, NULL((void*)0)); |
1843 | return SWITCH_STATUS_SUCCESS; |
1844 | } |
1845 | } |
1846 | |
1847 | |
1848 | if (session->endpoint_interface->io_routines->send_dtmf) { |
1849 | int send = 0; |
1850 | status = SWITCH_STATUS_SUCCESS; |
1851 | |
1852 | if (switch_channel_test_cap(session->channel, CC_QUEUEABLE_DTMF_DELAY) && (dtmf->digit == 'w' || dtmf->digit == 'W')) { |
1853 | send = 1; |
1854 | } else { |
1855 | if (dtmf->digit == 'w') { |
1856 | switch_yield(500000)switch_sleep(500000);; |
1857 | } else if (dtmf->digit == 'W') { |
1858 | switch_yield(1000000)switch_sleep(1000000);; |
1859 | } else { |
1860 | send = 1; |
1861 | } |
1862 | } |
1863 | |
1864 | if (send) { |
1865 | status = session->endpoint_interface->io_routines->send_dtmf(session, &new_dtmf); |
1866 | } |
1867 | } |
1868 | return status; |
1869 | } |
1870 | |
1871 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_send_dtmf_string(switch_core_session_t *session, const char *dtmf_string) |
1872 | { |
1873 | char *p; |
1874 | switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), DTMF_FLAG_SKIP_PROCESS, 0}; |
1875 | int sent = 0, dur; |
1876 | char *string; |
1877 | int i, argc; |
1878 | char *argv[256]; |
1879 | int dur_total = 0; |
1880 | |
1881 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_io.c", 1881, __PRETTY_FUNCTION__)); |
1882 | |
1883 | if (zstr(dtmf_string)_zstr(dtmf_string)) { |
1884 | return SWITCH_STATUS_FALSE; |
1885 | } |
1886 | |
1887 | if (*dtmf_string == '~') { |
1888 | dtmf_string++; |
1889 | dtmf.flags = 0; |
1890 | } |
1891 | |
1892 | if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) >= CS_HANGUP )) { |
1893 | return SWITCH_STATUS_FALSE; |
1894 | } |
1895 | |
1896 | |
1897 | if (strlen(dtmf_string) > 99) { |
1898 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1898, (const char*)(session), SWITCH_LOG_ERROR, "Attempt to send very large dtmf string ignored!\n"); |
1899 | return SWITCH_STATUS_FALSE; |
1900 | } |
1901 | |
1902 | string = switch_core_session_strdup(session, dtmf_string)switch_core_perform_session_strdup(session, dtmf_string, "src/switch_core_io.c" , (const char *)__func__, 1902); |
1903 | argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0]))); |
1904 | |
1905 | if (argc) { |
1906 | switch_channel_pre_answer(session->channel)switch_channel_perform_pre_answer(session->channel, "src/switch_core_io.c" , (const char *)__func__, 1906); |
1907 | } |
1908 | |
1909 | for (i = 0; i < argc; i++) { |
1910 | dtmf.duration = switch_core_default_dtmf_duration(0); |
1911 | dur = switch_core_default_dtmf_duration(0) / 8; |
1912 | if ((p = strchr(argv[i], '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (argv[i]) && ('@') == '\0' ? (char *) __rawmemchr (argv [i], '@') : __builtin_strchr (argv[i], '@'))))) { |
1913 | *p++ = '\0'; |
1914 | if ((dur = atoi(p)) > (int)switch_core_min_dtmf_duration(0) / 8) { |
1915 | dtmf.duration = dur * 8; |
1916 | } |
1917 | } |
1918 | |
1919 | |
1920 | for (p = argv[i]; p && *p; p++) { |
1921 | if (is_dtmf(*p)((*p > 47 && *p < 58) || (*p > 64 && *p < 69) || (*p > 96 && *p < 101) || *p == 35 || *p == 42 || *p == 87 || *p == 119 || *p == 70 || *p == 102 )) { |
1922 | dtmf.digit = *p; |
1923 | |
1924 | if (dtmf.digit != 'w' && dtmf.digit != 'W') { |
1925 | if (dtmf.duration > switch_core_max_dtmf_duration(0)) { |
1926 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1926, (const char*)(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", |
1927 | switch_channel_get_name(session->channel), dtmf.digit, dtmf.duration); |
1928 | dtmf.duration = switch_core_max_dtmf_duration(0); |
1929 | } else if (dtmf.duration < switch_core_min_dtmf_duration(0)) { |
1930 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1930, (const char*)(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", |
1931 | switch_channel_get_name(session->channel), dtmf.digit, dtmf.duration); |
1932 | dtmf.duration = switch_core_min_dtmf_duration(0); |
1933 | } |
1934 | } |
1935 | |
1936 | if (!dtmf.duration) { |
1937 | dtmf.duration = switch_core_default_dtmf_duration(0); |
1938 | } |
1939 | |
1940 | |
1941 | if (switch_core_session_send_dtmf(session, &dtmf) == SWITCH_STATUS_SUCCESS) { |
1942 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_io.c", (const char *)__func__, 1942, (const char*)(session), SWITCH_LOG_DEBUG, "%s send dtmf\ndigit=%c ms=%u samples=%u\n", |
1943 | switch_channel_get_name(session->channel), dtmf.digit, dur, dtmf.duration); |
1944 | sent++; |
1945 | dur_total += dtmf.duration + 2000; /* account for 250ms pause */ |
1946 | } |
1947 | } |
1948 | } |
1949 | |
1950 | if (dur_total) { |
1951 | char tmp[32] = ""; |
1952 | switch_snprintf(tmp, sizeof(tmp), "%d", dur_total / 8); |
1953 | switch_channel_set_variable(session->channel, "last_dtmf_duration", tmp)switch_channel_set_variable_var_check(session->channel, "last_dtmf_duration" , tmp, SWITCH_TRUE); |
1954 | } |
1955 | |
1956 | } |
1957 | return sent ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; |
1958 | } |
1959 | |
1960 | /* For Emacs: |
1961 | * Local Variables: |
1962 | * mode:c |
1963 | * indent-tabs-mode:t |
1964 | * tab-width:4 |
1965 | * c-basic-offset:4 |
1966 | * End: |
1967 | * For VIM: |
1968 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: |
1969 | */ |