switch_core_media_bug.c File Reference

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

Include dependency graph for switch_core_media_bug.c:

Go to the source code of this file.

Defines

#define MAX_BUG_BUFFER   1024 * 512

Functions

static void switch_core_media_bug_destroy (switch_media_bug_t *bug)
void switch_core_media_bug_pause (switch_core_session_t *session)
 Pause a media bug on the session.
void switch_core_media_bug_resume (switch_core_session_t *session)
 Resume a media bug on the session.
uint32_t switch_core_media_bug_test_flag (switch_media_bug_t *bug, uint32_t flag)
uint32_t switch_core_media_bug_set_flag (switch_media_bug_t *bug, uint32_t flag)
uint32_t switch_core_media_bug_clear_flag (switch_media_bug_t *bug, uint32_t flag)
switch_core_session_tswitch_core_media_bug_get_session (switch_media_bug_t *bug)
switch_frame_tswitch_core_media_bug_get_write_replace_frame (switch_media_bug_t *bug)
void switch_core_media_bug_set_write_replace_frame (switch_media_bug_t *bug, switch_frame_t *frame)
switch_frame_tswitch_core_media_bug_get_read_replace_frame (switch_media_bug_t *bug)
void switch_core_media_bug_set_read_replace_frame (switch_media_bug_t *bug, switch_frame_t *frame)
void switch_core_media_bug_set_read_demux_frame (switch_media_bug_t *bug, switch_frame_t *frame)
void * switch_core_media_bug_get_user_data (switch_media_bug_t *bug)
void switch_core_media_bug_flush (switch_media_bug_t *bug)
void switch_core_media_bug_inuse (switch_media_bug_t *bug, switch_size_t *readp, switch_size_t *writep)
switch_status_t switch_core_media_bug_set_pre_buffer_framecount (switch_media_bug_t *bug, uint32_t framecount)
switch_status_t switch_core_media_bug_read (switch_media_bug_t *bug, switch_frame_t *frame, switch_bool_t fill)
switch_status_t switch_core_media_bug_add (switch_core_session_t *session, const char *function, const char *target, switch_media_bug_callback_t callback, void *user_data, time_t stop_time, switch_media_bug_flag_t flags, switch_media_bug_t **new_bug)
switch_status_t switch_core_media_bug_flush_all (switch_core_session_t *session)
switch_status_t switch_core_media_bug_transfer_recordings (switch_core_session_t *orig_session, switch_core_session_t *new_session)
switch_status_t switch_core_media_bug_pop (switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop)
uint32_t switch_core_media_bug_count (switch_core_session_t *orig_session, const char *function)
switch_status_t switch_core_media_bug_exec_all (switch_core_session_t *orig_session, const char *function, switch_media_bug_exec_cb_t cb, void *user_data)
switch_status_t switch_core_media_bug_enumerate (switch_core_session_t *session, switch_stream_handle_t *stream)
switch_status_t switch_core_media_bug_remove_all_function (switch_core_session_t *session, const char *function)
switch_status_t switch_core_media_bug_close (switch_media_bug_t **bug)
switch_status_t switch_core_media_bug_remove (switch_core_session_t *session, switch_media_bug_t **bug)
uint32_t switch_core_media_bug_prune (switch_core_session_t *session)
switch_status_t switch_core_media_bug_remove_callback (switch_core_session_t *session, switch_media_bug_callback_t callback)
 Remove media bug callback.


Define Documentation

#define MAX_BUG_BUFFER   1024 * 512

Definition at line 392 of file switch_core_media_bug.c.

Referenced by switch_core_media_bug_add().


Function Documentation

switch_status_t switch_core_media_bug_add ( switch_core_session_t session,
const char *  function,
const char *  target,
switch_media_bug_callback_t  callback,
void *  user_data,
time_t  stop_time,
switch_media_bug_flag_t  flags,
switch_media_bug_t **  new_bug 
)

Definition at line 393 of file switch_core_media_bug.c.

References MAX_BUG_BUFFER, SMBF_ANSWER_REQ, SMBF_READ_PING, SMBF_READ_REPLACE, SMBF_READ_STREAM, SMBF_THREAD_LOCK, SMBF_WRITE_REPLACE, SMBF_WRITE_STREAM, SWITCH_ABC_TYPE_INIT, SWITCH_BUFFER_BLOCK_FRAMES, switch_buffer_create_dynamic(), SWITCH_BUFFER_START_FRAMES, switch_channel_event_set_data(), switch_channel_get_name(), switch_channel_get_variable, switch_channel_media_ready, switch_channel_pre_answer, SWITCH_CHANNEL_SESSION_LOG, switch_core_media_bug_destroy(), switch_core_session_alloc, switch_core_session_get_read_impl(), switch_core_session_get_write_impl(), switch_core_session_strdup, switch_event_add_header(), switch_event_create, switch_event_fire, SWITCH_EVENT_MEDIA_BUG_START, SWITCH_FALSE, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), switch_thread_self(), and switch_true().

00400 {
00401         switch_media_bug_t *bug;        //, *bp;
00402         switch_size_t bytes;
00403         switch_event_t *event;
00404 
00405         const char *p;
00406 
00407         if (!switch_channel_media_ready(session->channel)) {
00408                 if (switch_channel_pre_answer(session->channel) != SWITCH_STATUS_SUCCESS) {
00409                         return SWITCH_STATUS_FALSE;
00410                 }
00411         }
00412 
00413 
00414 
00415         *new_bug = NULL;
00416 
00417 
00418         if ((p = switch_channel_get_variable(session->channel, "media_bug_answer_req")) && switch_true(p)) {
00419                 flags |= SMBF_ANSWER_REQ;
00420         }
00421 #if 0
00422         if (flags & SMBF_WRITE_REPLACE) {
00423                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00424                 for (bp = session->bugs; bp; bp = bp->next) {
00425                         if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
00426                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
00427                                 switch_thread_rwlock_unlock(session->bug_rwlock);
00428                                 return SWITCH_STATUS_GENERR;
00429                         }
00430                 }
00431                 switch_thread_rwlock_unlock(session->bug_rwlock);
00432         }
00433 
00434         if (flags & SMBF_READ_REPLACE) {
00435                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00436                 for (bp = session->bugs; bp; bp = bp->next) {
00437                         if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
00438                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
00439                                 switch_thread_rwlock_unlock(session->bug_rwlock);
00440                                 return SWITCH_STATUS_GENERR;
00441                         }
00442                 }
00443                 switch_thread_rwlock_unlock(session->bug_rwlock);
00444         }
00445 #endif
00446 
00447         if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) {
00448                 return SWITCH_STATUS_MEMERR;
00449         }
00450 
00451         bug->callback = callback;
00452         bug->user_data = user_data;
00453         bug->session = session;
00454         bug->flags = flags;
00455         bug->function = "N/A";
00456         bug->target = "N/A";
00457 
00458         switch_core_session_get_read_impl(session, &bug->read_impl);
00459         switch_core_session_get_write_impl(session, &bug->write_impl);
00460 
00461         if (function) {
00462                 bug->function = switch_core_session_strdup(session, function);
00463         }
00464 
00465         if (target) {
00466                 bug->target = switch_core_session_strdup(session, target);
00467         }
00468         
00469         bug->stop_time = stop_time;
00470         bytes = bug->read_impl.decoded_bytes_per_packet;
00471 
00472         if (!bug->flags) {
00473                 bug->flags = (SMBF_READ_STREAM | SMBF_WRITE_STREAM);
00474         }
00475 
00476         if (switch_test_flag(bug, SMBF_READ_STREAM) || switch_test_flag(bug, SMBF_READ_PING)) {
00477                 switch_buffer_create_dynamic(&bug->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER);
00478                 switch_mutex_init(&bug->read_mutex, SWITCH_MUTEX_NESTED, session->pool);
00479         }
00480 
00481         bytes = bug->write_impl.decoded_bytes_per_packet;
00482 
00483         if (switch_test_flag(bug, SMBF_WRITE_STREAM)) {
00484                 switch_buffer_create_dynamic(&bug->raw_write_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER);
00485                 switch_mutex_init(&bug->write_mutex, SWITCH_MUTEX_NESTED, session->pool);
00486         }
00487 
00488         if ((bug->flags & SMBF_THREAD_LOCK)) {
00489                 bug->thread_id = switch_thread_self();
00490         }
00491 
00492         if (bug->callback) {
00493                 switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT);
00494                 if (result == SWITCH_FALSE) {
00495                         switch_core_media_bug_destroy(bug);
00496                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error attaching BUG to %s\n",
00497                                                           switch_channel_get_name(session->channel));
00498                         return SWITCH_STATUS_GENERR;
00499                 }
00500         }
00501 
00502         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attaching BUG to %s\n", switch_channel_get_name(session->channel));
00503         bug->ready = 1;
00504         switch_thread_rwlock_wrlock(session->bug_rwlock);
00505         bug->next = session->bugs;
00506         session->bugs = bug;
00507         switch_thread_rwlock_unlock(session->bug_rwlock);
00508         *new_bug = bug;
00509 
00510         if (switch_event_create(&event, SWITCH_EVENT_MEDIA_BUG_START) == SWITCH_STATUS_SUCCESS) {
00511                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function);
00512                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target);
00513                 switch_channel_event_set_data(session->channel, event);
00514                 switch_event_fire(&event);
00515         }
00516 
00517         return SWITCH_STATUS_SUCCESS;
00518 }

uint32_t switch_core_media_bug_clear_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 81 of file switch_core_media_bug.c.

References switch_clear_flag.

00082 {
00083         return switch_clear_flag(bug, flag);
00084 }

switch_status_t switch_core_media_bug_close ( switch_media_bug_t **  bug  ) 

Definition at line 706 of file switch_core_media_bug.c.

References switch_media_bug::callback, switch_core_session::channel, switch_media_bug::ready, switch_media_bug::session, SMBF_LOCK, SWITCH_ABC_TYPE_CLOSE, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_media_bug_destroy(), switch_core_media_bug_get_session(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_self(), switch_media_bug::thread_id, and switch_media_bug::user_data.

00707 {
00708         switch_media_bug_t *bp = *bug;
00709         if (bp) {
00710                 if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)) {
00711                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(*bug)), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
00712                         return SWITCH_STATUS_FALSE;
00713                 }
00714 
00715                 if (bp->callback) {
00716                         bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
00717                         bp->ready = 0;
00718                 }
00719                 switch_core_media_bug_destroy(bp);
00720                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(*bug)), SWITCH_LOG_DEBUG, "Removing BUG from %s\n",
00721                                                   switch_channel_get_name(bp->session->channel));
00722                 *bug = NULL;
00723                 return SWITCH_STATUS_SUCCESS;
00724         }
00725 
00726         return SWITCH_STATUS_FALSE;
00727 }

static void switch_core_media_bug_destroy ( switch_media_bug_t bug  )  [static]

Definition at line 38 of file switch_core_media_bug.c.

References switch_core_session::channel, switch_media_bug::function, switch_media_bug::raw_read_buffer, switch_media_bug::raw_write_buffer, switch_media_bug::session, switch_buffer_destroy(), switch_channel_event_set_data(), switch_event_add_header(), switch_event_create, switch_event_fire, SWITCH_EVENT_MEDIA_BUG_STOP, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, and switch_media_bug::target.

Referenced by switch_core_media_bug_add(), switch_core_media_bug_close(), and switch_core_media_bug_remove_all_function().

00039 {
00040         switch_event_t *event = NULL;
00041 
00042         if (bug->raw_read_buffer) {
00043                 switch_buffer_destroy(&bug->raw_read_buffer);
00044         }
00045 
00046         if (bug->raw_write_buffer) {
00047                 switch_buffer_destroy(&bug->raw_write_buffer);
00048         }
00049 
00050         if (switch_event_create(&event, SWITCH_EVENT_MEDIA_BUG_STOP) == SWITCH_STATUS_SUCCESS) {
00051                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function);
00052                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target);
00053                 if (bug->session) switch_channel_event_set_data(bug->session->channel, event);
00054                 switch_event_fire(&event);
00055         }
00056 }

void switch_core_media_bug_flush ( switch_media_bug_t bug  ) 

Definition at line 121 of file switch_core_media_bug.c.

References switch_buffer_zero(), switch_mutex_lock(), and switch_mutex_unlock().

00122 {
00123 
00124         bug->record_pre_buffer_count = 0;
00125 
00126         if (bug->raw_read_buffer) {
00127                 switch_mutex_lock(bug->read_mutex);
00128                 switch_buffer_zero(bug->raw_read_buffer);
00129                 switch_mutex_unlock(bug->read_mutex);
00130         }
00131 
00132         if (bug->raw_write_buffer) {
00133                 switch_mutex_lock(bug->write_mutex);
00134                 switch_buffer_zero(bug->raw_write_buffer);
00135                 switch_mutex_unlock(bug->write_mutex);
00136         }
00137 
00138         bug->record_frame_size = 0;
00139         bug->record_pre_buffer_count = 0;
00140 }

switch_status_t switch_core_media_bug_flush_all ( switch_core_session_t session  ) 

Definition at line 521 of file switch_core_media_bug.c.

References switch_media_bug::next, switch_core_media_bug_flush(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_rwlock_unlock(), and switch_thread_rwlock_wrlock().

00522 {
00523         switch_media_bug_t *bp;
00524 
00525         if (session->bugs) {
00526                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00527                 for (bp = session->bugs; bp; bp = bp->next) {
00528                         switch_core_media_bug_flush(bp);
00529                 }
00530                 switch_thread_rwlock_unlock(session->bug_rwlock);
00531                 return SWITCH_STATUS_SUCCESS;
00532         }
00533 
00534         return SWITCH_STATUS_FALSE;
00535 }

switch_frame_t* switch_core_media_bug_get_read_replace_frame ( switch_media_bug_t bug  ) 

Definition at line 101 of file switch_core_media_bug.c.

00102 {
00103         return bug->read_replace_frame_in;
00104 }

switch_core_session_t* switch_core_media_bug_get_session ( switch_media_bug_t bug  ) 

Definition at line 86 of file switch_core_media_bug.c.

00087 {
00088         return bug->session;
00089 }

void* switch_core_media_bug_get_user_data ( switch_media_bug_t bug  ) 

Definition at line 116 of file switch_core_media_bug.c.

00117 {
00118         return bug->user_data;
00119 }

switch_frame_t* switch_core_media_bug_get_write_replace_frame ( switch_media_bug_t bug  ) 

Definition at line 91 of file switch_core_media_bug.c.

00092 {
00093         return bug->write_replace_frame_in;
00094 }

switch_status_t switch_core_media_bug_read ( switch_media_bug_t bug,
switch_frame_t frame,
switch_bool_t  fill 
)

Definition at line 168 of file switch_core_media_bug.c.

References switch_codec_implementation::actual_samples_per_second, switch_codec_implementation::decoded_bytes_per_packet, SMBF_READ_STREAM, SMBF_STEREO, SMBF_STEREO_SWAP, SMBF_WRITE_STREAM, switch_assert, switch_buffer_inuse(), switch_buffer_read(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_media_bug_flush(), switch_core_media_bug_get_session(), switch_core_session_get_partner(), switch_core_session_get_read_impl(), switch_core_session_rwunlock(), SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_normalize_to_16bit, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_SMAX, SWITCH_SMIN, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_test_flag.

00169 {
00170         switch_size_t bytes = 0, datalen = 0;
00171         int16_t *dp, *fp;
00172         uint32_t x;
00173         size_t rlen = 0;
00174         size_t wlen = 0;
00175         uint32_t blen;
00176         switch_codec_implementation_t read_impl = { 0 };
00177         int16_t *tp;
00178         switch_size_t do_read = 0, do_write = 0;
00179         int fill_read = 0, fill_write = 0;
00180 
00181 
00182         switch_core_session_get_read_impl(bug->session, &read_impl);
00183 
00184         bytes = read_impl.decoded_bytes_per_packet;
00185 
00186 #ifdef TESTINGONLY
00187         if (0 && bug->session->recur_buffer_len) {
00188                 frame->datalen = bug->session->recur_buffer_len;
00189                 frame->samples = bug->session->recur_buffer_len / sizeof(int16_t);
00190                 frame->rate = read_impl.actual_samples_per_second;
00191                 frame->codec = NULL;
00192                 memcpy(frame->data, bug->session->recur_buffer, bug->session->recur_buffer_len);
00193                 return SWITCH_STATUS_SUCCESS;
00194         }
00195 #endif
00196 
00197 
00198         if (frame->buflen < bytes) {
00199                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "%s frame buffer too small!\n",
00200                                                   switch_channel_get_name(bug->session->channel));
00201                 return SWITCH_STATUS_FALSE;
00202         }
00203 
00204         if (!(bug->raw_read_buffer && (bug->raw_write_buffer || !switch_test_flag(bug, SMBF_WRITE_STREAM)))) {
00205                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "%s Buffer Error\n",
00206                                                   switch_channel_get_name(bug->session->channel));
00207                 return SWITCH_STATUS_FALSE;
00208         }
00209 
00210         frame->flags = 0;
00211         frame->datalen = 0;
00212 
00213         if (switch_test_flag(bug, SMBF_READ_STREAM)) {
00214                 switch_mutex_lock(bug->read_mutex);
00215                 do_read = switch_buffer_inuse(bug->raw_read_buffer);
00216                 switch_mutex_unlock(bug->read_mutex);
00217         }
00218 
00219         if (switch_test_flag(bug, SMBF_WRITE_STREAM)) {
00220                 switch_mutex_lock(bug->write_mutex);
00221                 do_write = switch_buffer_inuse(bug->raw_write_buffer);
00222                 switch_mutex_unlock(bug->write_mutex);
00223         }
00224 
00225         if (bug->record_frame_size && bug->record_pre_buffer_max && (do_read || do_write) && bug->record_pre_buffer_count < bug->record_pre_buffer_max) {
00226                 bug->record_pre_buffer_count++;
00227                 return SWITCH_STATUS_FALSE;
00228         }
00229 
00230         if (!bug->record_frame_size) {
00231                 if (do_read && do_write) {
00232                         switch_size_t frame_size;
00233                         switch_codec_implementation_t read_impl = { 0 };
00234                         switch_codec_implementation_t other_read_impl = { 0 };
00235                         switch_core_session_t *other_session;
00236                         
00237                         switch_core_session_get_read_impl(bug->session, &read_impl);
00238                         frame_size = read_impl.decoded_bytes_per_packet;
00239                         
00240                         if (switch_core_session_get_partner(bug->session, &other_session) == SWITCH_STATUS_SUCCESS) {
00241                                 switch_core_session_get_read_impl(other_session, &other_read_impl);
00242                                 switch_core_session_rwunlock(other_session);
00243                                 
00244                                 if (read_impl.decoded_bytes_per_packet < other_read_impl.decoded_bytes_per_packet) {
00245                                         frame_size = other_read_impl.decoded_bytes_per_packet;
00246                                 }
00247                         }
00248                         
00249                         bug->record_frame_size = frame_size;
00250                 }
00251         }
00252 
00253 
00254         if (bug->record_frame_size) {
00255                 if ((do_read && do_read < bug->record_frame_size) || (do_write && do_write < bug->record_frame_size)) {
00256                         return SWITCH_STATUS_FALSE;
00257                 }
00258 
00259                 if (do_read && do_read > bug->record_frame_size) {
00260                         do_read = bug->record_frame_size;
00261                 }
00262 
00263                 if (do_write && do_write > bug->record_frame_size) {
00264                         do_write = bug->record_frame_size;
00265                 }
00266         }
00267 
00268         fill_read = !do_read;
00269         fill_write = !do_write;
00270 
00271         if (fill_read && fill_write) {
00272                 return SWITCH_STATUS_FALSE;
00273         }
00274 
00275         if (do_read && do_read > SWITCH_RECOMMENDED_BUFFER_SIZE) {
00276                 do_read = 1280;
00277         }
00278 
00279         if (do_write && do_write > SWITCH_RECOMMENDED_BUFFER_SIZE) {
00280                 do_write = 1280;
00281         }
00282         
00283         if (do_read) {
00284                 switch_mutex_lock(bug->read_mutex);
00285                 frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, do_read);
00286                 if (frame->datalen != do_read) {
00287                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "Framing Error Reading!\n");
00288                         switch_core_media_bug_flush(bug);
00289                         switch_mutex_unlock(bug->read_mutex);
00290                         return SWITCH_STATUS_FALSE;
00291                 }
00292                 switch_mutex_unlock(bug->read_mutex);
00293         } else if (fill_read) {
00294                 frame->datalen = bytes;
00295                 memset(frame->data, 255, frame->datalen);
00296         }
00297 
00298         if (do_write) {
00299                 switch_assert(bug->raw_write_buffer);
00300                 switch_mutex_lock(bug->write_mutex);
00301                 datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, do_write);
00302                 if (datalen != do_write) {
00303                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "Framing Error Writing!\n");
00304                         switch_core_media_bug_flush(bug);
00305                         switch_mutex_unlock(bug->write_mutex);
00306                         return SWITCH_STATUS_FALSE;
00307                 }
00308                 switch_mutex_unlock(bug->write_mutex);
00309         } else if (fill_write) {
00310                 datalen = bytes;
00311                 memset(bug->data, 255, datalen);
00312         }
00313 
00314         tp = bug->tmp;
00315         dp = (int16_t *) bug->data;
00316         fp = (int16_t *) frame->data;
00317         rlen = frame->datalen / 2;
00318         wlen = datalen / 2;
00319         blen = bytes / 2;
00320 
00321         if (switch_test_flag(bug, SMBF_STEREO)) {
00322                 int16_t *left, *right;
00323                 size_t left_len, right_len;
00324                 if (switch_test_flag(bug, SMBF_STEREO_SWAP)) {
00325                         left = dp; /* write stream */
00326                         left_len = wlen;
00327                         right = fp; /* read stream */
00328                         right_len = rlen;
00329                 } else {
00330                         left = fp; /* read stream */
00331                         left_len = rlen;
00332                         right = dp; /* write stream */
00333                         right_len = wlen;
00334                 }
00335                 for (x = 0; x < blen; x++) {
00336                         if (x < left_len) {
00337                                 *(tp++) = *(left + x);
00338                         } else {
00339                                 *(tp++) = 0;
00340                         }
00341                         if (x < right_len) {
00342                                 *(tp++) = *(right + x);
00343                         } else {
00344                                 *(tp++) = 0;
00345                         }
00346                 }
00347                 memcpy(frame->data, bug->tmp, bytes * 2);
00348         } else {
00349                 for (x = 0; x < blen; x++) {
00350                         int32_t w = 0, r = 0, z = 0;
00351                         
00352                         if (x < rlen) {
00353                                 r = (int32_t) * (fp + x);
00354                         }
00355 
00356                         if (x < wlen) {
00357                                 w = (int32_t) * (dp + x);
00358                         }
00359                         
00360                         z = w + r;
00361 
00362                         if (z > SWITCH_SMAX || z < SWITCH_SMIN) {
00363                                 if (r) z += (r/2);
00364                                 if (w) z += (w/2);
00365                         }
00366 
00367                         switch_normalize_to_16bit(z);
00368 
00369                         *(fp + x) = (int16_t) z;
00370                 }
00371         }
00372 
00373         frame->datalen = bytes;
00374         frame->samples = bytes / sizeof(int16_t);
00375         frame->rate = read_impl.actual_samples_per_second;
00376         frame->codec = NULL;
00377 
00378         if (fill_read && fill_write) {
00379                 return SWITCH_STATUS_BREAK;
00380         }
00381 
00382         if (fill_read || fill_write) {
00383                 return SWITCH_STATUS_BREAK;
00384         }
00385 
00386         memcpy(bug->session->recur_buffer, frame->data, frame->datalen);
00387         bug->session->recur_buffer_len = frame->datalen;
00388         
00389         return SWITCH_STATUS_SUCCESS;
00390 }

switch_status_t switch_core_media_bug_remove ( switch_core_session_t session,
switch_media_bug_t **  bug 
)

Definition at line 729 of file switch_core_media_bug.c.

References switch_media_bug::next, switch_media_bug::ready, SMBF_LOCK, switch_core_codec_destroy(), switch_core_codec_ready(), switch_core_media_bug_close(), switch_core_media_bug_test_flag(), SWITCH_STATUS_FALSE, switch_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), switch_thread_self(), and switch_media_bug::thread_id.

00730 {
00731         switch_media_bug_t *bp = NULL, *last = NULL;
00732         switch_status_t status = SWITCH_STATUS_FALSE;
00733         
00734         if (switch_core_media_bug_test_flag(*bug, SMBF_LOCK)) {
00735                 return status;
00736         }
00737 
00738         switch_thread_rwlock_wrlock(session->bug_rwlock);
00739         if (session->bugs) {
00740                 for (bp = session->bugs; bp; bp = bp->next) {
00741                         if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) {
00742                                 if (last) {
00743                                         last->next = bp->next;
00744                                 } else {
00745                                         session->bugs = bp->next;
00746                                 }
00747                                 break;
00748                         }
00749 
00750                         last = bp;
00751                 }
00752         }
00753 
00754         if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
00755                 switch_core_codec_destroy(&session->bug_codec);
00756         }
00757 
00758         switch_thread_rwlock_unlock(session->bug_rwlock);
00759 
00760         if (bp) {
00761                 status = switch_core_media_bug_close(&bp);
00762         }
00763         
00764         return status;
00765 }

switch_status_t switch_core_media_bug_remove_all_function ( switch_core_session_t session,
const char *  function 
)

Definition at line 670 of file switch_core_media_bug.c.

References switch_media_bug::callback, switch_media_bug::function, switch_media_bug::next, SMBF_LOCK, SWITCH_ABC_TYPE_CLOSE, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_codec_destroy(), switch_core_codec_ready(), switch_core_media_bug_destroy(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), switch_thread_self(), switch_media_bug::thread_id, switch_media_bug::user_data, and zstr.

00671 {
00672         switch_media_bug_t *bp;
00673         switch_status_t status = SWITCH_STATUS_FALSE;
00674 
00675         if (session->bugs) {
00676                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00677                 for (bp = session->bugs; bp; bp = bp->next) {
00678                         if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)) {
00679                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
00680                                 continue;
00681                         }
00682                         
00683                         if (!zstr(function) && strcmp(bp->function, function)) {
00684                                 continue;
00685                         }
00686 
00687 
00688                         if (bp->callback) {
00689                                 bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
00690                         }
00691                         switch_core_media_bug_destroy(bp);
00692                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(session->channel));
00693                 }
00694                 session->bugs = NULL;
00695                 switch_thread_rwlock_unlock(session->bug_rwlock);
00696                 status = SWITCH_STATUS_SUCCESS;
00697         }
00698 
00699         if (switch_core_codec_ready(&session->bug_codec)) {
00700                 switch_core_codec_destroy(&session->bug_codec);
00701         }
00702 
00703         return status;
00704 }

uint32_t switch_core_media_bug_set_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 73 of file switch_core_media_bug.c.

References SMBF_LOCK, SMBF_PRUNE, switch_clear_flag, and switch_set_flag.

00074 {
00075         if ((flag & SMBF_PRUNE)) {
00076                 switch_clear_flag(bug, SMBF_LOCK);
00077         }
00078         return switch_set_flag(bug, flag);
00079 }

void switch_core_media_bug_set_read_demux_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 111 of file switch_core_media_bug.c.

00112 {
00113         bug->read_demux_frame = frame;
00114 }

void switch_core_media_bug_set_read_replace_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 106 of file switch_core_media_bug.c.

00107 {
00108         bug->read_replace_frame_out = frame;
00109 }

void switch_core_media_bug_set_write_replace_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 96 of file switch_core_media_bug.c.

00097 {
00098         bug->write_replace_frame_out = frame;
00099 }

uint32_t switch_core_media_bug_test_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 68 of file switch_core_media_bug.c.

References switch_test_flag.

00069 {
00070         return switch_test_flag(bug, flag);
00071 }


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