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

switch_core_media_bug.c File Reference


Defines

#define MAX_BUG_BUFFER   1024 * 512

Functions

uint32_t switch_core_media_bug_test_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_get_user_data (switch_media_bug_t *bug)
switch_status_t switch_core_media_bug_read (switch_media_bug_t *bug, switch_frame_t *frame)
switch_status_t switch_core_media_bug_add (switch_core_session_t *session, 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_remove_all (switch_core_session_t *session)
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)


Define Documentation

#define MAX_BUG_BUFFER   1024 * 512
 


Function Documentation

switch_status_t switch_core_media_bug_add switch_core_session_t session,
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
 

00185 {
00186         switch_media_bug_t *bug;//, *bp;
00187         switch_size_t bytes;
00188 
00189         if (flags & SMBF_WRITE_REPLACE) {
00190 #if 0
00191                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00192                 for (bp = session->bugs; bp; bp = bp->next) {
00193                         if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
00194                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
00195                                 switch_thread_rwlock_unlock(session->bug_rwlock);
00196                                 return SWITCH_STATUS_GENERR;
00197                         }
00198                 }
00199                 switch_thread_rwlock_unlock(session->bug_rwlock);
00200 #endif
00201         }
00202 
00203         if (flags & SMBF_READ_REPLACE) {
00204 #if 0
00205                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00206                 for (bp = session->bugs; bp; bp = bp->next) {
00207                         if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
00208                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
00209                                 switch_thread_rwlock_unlock(session->bug_rwlock);
00210                                 return SWITCH_STATUS_GENERR;
00211                         }
00212                 }
00213                 switch_thread_rwlock_unlock(session->bug_rwlock);
00214 #endif
00215         }
00216 
00217         if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) {
00218                 return SWITCH_STATUS_MEMERR;
00219         }
00220 
00221         bug->callback = callback;
00222         bug->user_data = user_data;
00223         bug->session = session;
00224         bug->flags = flags;
00225 
00226         bug->stop_time = stop_time;
00227         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attaching BUG to %s\n", switch_channel_get_name(session->channel));
00228         bytes = session->read_codec->implementation->bytes_per_frame;
00229 
00230         if (!bug->flags) {
00231                 bug->flags = (SMBF_READ_STREAM | SMBF_WRITE_STREAM);
00232         }
00233 
00234         if (switch_test_flag(bug, SMBF_READ_STREAM) || switch_test_flag(bug, SMBF_READ_PING)) {
00235                 switch_buffer_create_dynamic(&bug->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER);
00236                 switch_mutex_init(&bug->read_mutex, SWITCH_MUTEX_NESTED, session->pool);
00237         }
00238 
00239         bytes = session->write_codec->implementation->bytes_per_frame;
00240 
00241         if (switch_test_flag(bug, SMBF_WRITE_STREAM)) {
00242                 switch_buffer_create_dynamic(&bug->raw_write_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER);
00243                 switch_mutex_init(&bug->write_mutex, SWITCH_MUTEX_NESTED, session->pool);
00244         }
00245 
00246         if ((bug->flags & SMBF_THREAD_LOCK)) {
00247                 bug->thread_id = switch_thread_self();
00248         }
00249 
00250         bug->ready = 1;
00251         switch_thread_rwlock_wrlock(session->bug_rwlock);
00252         bug->next = session->bugs;
00253         session->bugs = bug;
00254         switch_thread_rwlock_unlock(session->bug_rwlock);
00255         *new_bug = bug;
00256 
00257         if (bug->callback) {
00258                 switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT);
00259                 if (result == SWITCH_FALSE) {
00260                         return switch_core_media_bug_remove(session, new_bug);
00261                 }
00262         }
00263 
00264         return SWITCH_STATUS_SUCCESS;
00265 }

Here is the call graph for this function:

switch_status_t switch_core_media_bug_close switch_media_bug_t **  bug  ) 
 

00299 {
00300         switch_media_bug_t *bp = *bug;
00301         if (bp) {
00302                 if (bp->thread_id && bp->thread_id != switch_thread_self()) {
00303                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
00304                         return SWITCH_STATUS_FALSE;
00305                 }
00306 
00307                 if (bp->callback) {
00308                         bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
00309                         bp->ready = 0;
00310                 }
00311                 switch_core_media_bug_destroy(bp);
00312                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(bp->session->channel));
00313                 *bug = NULL;
00314                 return SWITCH_STATUS_SUCCESS;
00315         }
00316         
00317         return SWITCH_STATUS_FALSE;
00318 }

Here is the call graph for this function:

switch_frame_t* switch_core_media_bug_get_read_replace_frame switch_media_bug_t bug  ) 
 

00065 {
00066         return bug->read_replace_frame_in;
00067 }

switch_core_session_t* switch_core_media_bug_get_session switch_media_bug_t bug  ) 
 

00050 {
00051         return bug->session;
00052 }

void* switch_core_media_bug_get_user_data switch_media_bug_t bug  ) 
 

00075 {
00076         return bug->user_data;
00077 }

switch_frame_t* switch_core_media_bug_get_write_replace_frame switch_media_bug_t bug  ) 
 

00055 {
00056         return bug->write_replace_frame_in;
00057 }

switch_status_t switch_core_media_bug_read switch_media_bug_t bug,
switch_frame_t frame
 

00080 {
00081         uint32_t bytes = 0;
00082         uint32_t datalen = 0;
00083         int16_t *dp, *fp;
00084         uint32_t x;
00085         size_t rlen = 0;
00086         size_t wlen = 0;
00087         uint32_t blen;
00088         size_t rdlen = 0;
00089         uint32_t maxlen;
00090         switch_codec_t *read_codec = switch_core_session_get_read_codec(bug->session);
00091 
00092         if (bug->raw_read_buffer) {
00093                 rlen = switch_buffer_inuse(bug->raw_read_buffer);
00094         }
00095 
00096         if (bug->raw_write_buffer) {
00097                 wlen = switch_buffer_inuse(bug->raw_write_buffer);
00098         }
00099 
00100         if ((bug->raw_read_buffer && bug->raw_write_buffer) && (!rlen && !wlen)) {
00101                 return SWITCH_STATUS_FALSE;
00102         }
00103         
00104         maxlen = SWITCH_RECOMMENDED_BUFFER_SIZE > frame->buflen ? frame->buflen : SWITCH_RECOMMENDED_BUFFER_SIZE;
00105 
00106         if ((rdlen = rlen > wlen ? wlen : rlen) > maxlen) {
00107                 rdlen = maxlen;
00108         }
00109 
00110         if (!rdlen) {
00111                 rdlen = maxlen;
00112         }
00113 
00114         frame->datalen = 0;
00115 
00116         if (rlen) {
00117                 switch_mutex_lock(bug->read_mutex);
00118 
00119                 frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, rdlen);
00120                 switch_mutex_unlock(bug->read_mutex);
00121         }
00122 
00123         if (wlen) {
00124                 switch_mutex_lock(bug->write_mutex);
00125                 datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, rdlen);
00126                 switch_mutex_unlock(bug->write_mutex);
00127         }
00128 
00129 
00130         bytes = (datalen > frame->datalen) ? datalen : frame->datalen;
00131         switch_assert( bytes <= maxlen );
00132         
00133         if (bytes) {
00134                 int16_t *tp = bug->tmp;
00135                 
00136                 dp = (int16_t *) bug->data;
00137                 fp = (int16_t *) frame->data;
00138                 rlen = frame->datalen / 2;
00139                 wlen = datalen / 2;
00140                 blen = bytes / 2;
00141 
00142                 if (switch_test_flag(bug, SMBF_STEREO)) {
00143                         for (x = 0; x < blen; x++) {
00144                                 if (x < rlen) {
00145                                         *(tp++) = *(fp + x);
00146                                 } else {
00147                                         *(tp++) = 0;
00148                                 }
00149                                 if (x < wlen) {
00150                                         *(tp++) = *(dp + x);
00151                                 } else {
00152                                         *(tp++) = 0;
00153                                 }
00154                         }
00155                         memcpy(frame->data, bug->tmp, bytes * 2);
00156                 } else {
00157                         for (x = 0; x < blen; x++) {
00158                                 int32_t z = 0;
00159 
00160                                 if (x < rlen) {
00161                                         z += (int32_t) *(fp + x);
00162                                 }
00163                                 if (x < wlen) {
00164                                         z += (int32_t) *(dp + x);
00165                                 }
00166                                 switch_normalize_to_16bit(z);
00167                                 *(fp + x) = (int16_t) z;
00168                         }
00169                 }
00170 
00171                 frame->datalen = bytes;
00172                 frame->samples = bytes / sizeof(int16_t);
00173                 frame->rate = read_codec->implementation->actual_samples_per_second;
00174                 
00175                 return SWITCH_STATUS_SUCCESS;
00176         }
00177         
00178         return SWITCH_STATUS_FALSE;
00179 }

Here is the call graph for this function:

switch_status_t switch_core_media_bug_remove switch_core_session_t session,
switch_media_bug_t **  bug
 

00321 {
00322         switch_media_bug_t *bp = NULL, *last = NULL;
00323         switch_status_t status = SWITCH_STATUS_FALSE;
00324 
00325         if (session->bugs) {
00326                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00327                 for (bp = session->bugs; bp; bp = bp->next) {
00328                         if (bp->thread_id && bp->thread_id != switch_thread_self()) {
00329                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
00330                                 continue;
00331                         }
00332 
00333                         if (!bp->ready) {
00334                                 continue;
00335                         }
00336                         if (bp == *bug) {
00337                                 if (last) {
00338                                         last->next = bp->next;
00339                                 } else {
00340                                         session->bugs = bp->next;
00341                                 }
00342                                 break;
00343                         }
00344                         last = bp;
00345                 }
00346                 switch_thread_rwlock_unlock(session->bug_rwlock);
00347                 status = switch_core_media_bug_close(&bp);
00348         }
00349 
00350         if (!session->bugs && session->bug_codec.implementation) {
00351                 switch_core_codec_destroy(&session->bug_codec);
00352         }
00353         
00354         return status;
00355 }

Here is the call graph for this function:

switch_status_t switch_core_media_bug_remove_all switch_core_session_t session  ) 
 

00269 {
00270         switch_media_bug_t *bp;
00271 
00272         if (session->bugs) {
00273                 switch_thread_rwlock_wrlock(session->bug_rwlock);
00274                 for (bp = session->bugs; bp; bp = bp->next) {
00275                         if (bp->thread_id && bp->thread_id != switch_thread_self()) {
00276                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
00277                                 continue;
00278                         }
00279 
00280                         if (bp->callback) {
00281                                 bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
00282                         }
00283                         switch_core_media_bug_destroy(bp);
00284                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(session->channel));
00285                 }
00286                 session->bugs = NULL;
00287                 switch_thread_rwlock_unlock(session->bug_rwlock);
00288                 return SWITCH_STATUS_SUCCESS;
00289         }
00290         
00291         if (session->bug_codec.implementation) {
00292                 switch_core_codec_destroy(&session->bug_codec);
00293         }
00294 
00295         return SWITCH_STATUS_FALSE;
00296 }

Here is the call graph for this function:

void switch_core_media_bug_set_read_replace_frame switch_media_bug_t bug,
switch_frame_t frame
 

00070 {
00071         bug->read_replace_frame_out = frame;
00072 }

void switch_core_media_bug_set_write_replace_frame switch_media_bug_t bug,
switch_frame_t frame
 

00060 {
00061         bug->write_replace_frame_out = frame;
00062 }

uint32_t switch_core_media_bug_test_flag switch_media_bug_t bug,
uint32_t  flag
 

00045 {
00046         return switch_test_flag(bug, flag);
00047 }


Generated on Mon May 26 22:06:52 2008 for FreeSWITCH by  doxygen 1.3.9.1