diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index 45dc4cebbe..753d4f56c8 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -104,105 +104,88 @@ SWITCH_DECLARE(void) switch_core_media_bug_flush(switch_media_bug_t *bug) SWITCH_DECLARE(switch_status_t) switch_core_media_bug_read(switch_media_bug_t *bug, switch_frame_t *frame) { - uint32_t bytes = 0; - uint32_t datalen = 0; + switch_size_t bytes = 0, datalen = 0; int16_t *dp, *fp; uint32_t x; size_t rlen = 0; size_t wlen = 0; uint32_t blen; - size_t rdlen = 0; - uint32_t maxlen; switch_codec_implementation_t read_impl = {0}; + int16_t *tp; + switch_core_session_get_read_impl(bug->session, &read_impl); - if (bug->raw_read_buffer) { - rlen = switch_buffer_inuse(bug->raw_read_buffer); - } + bytes = read_impl.decoded_bytes_per_packet; - if (bug->raw_write_buffer) { - wlen = switch_buffer_inuse(bug->raw_write_buffer); - } - - if ((bug->raw_read_buffer && bug->raw_write_buffer) && (!rlen && !wlen)) { + if (frame->buflen < bytes) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s frame buffer too small!\n", switch_channel_get_name(bug->session->channel)); return SWITCH_STATUS_FALSE; } - - maxlen = SWITCH_RECOMMENDED_BUFFER_SIZE > frame->buflen ? frame->buflen : SWITCH_RECOMMENDED_BUFFER_SIZE; - - if ((rdlen = rlen > wlen ? wlen : rlen) > maxlen) { - rdlen = maxlen; + + if (!(bug->raw_read_buffer && bug->raw_write_buffer)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%sBuffer Error\n", switch_channel_get_name(bug->session->channel)); } - - if (!rdlen) { - rdlen = maxlen; - } - + frame->datalen = 0; - - if (rlen) { - switch_mutex_lock(bug->read_mutex); - - frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, rdlen); - switch_mutex_unlock(bug->read_mutex); + + switch_mutex_lock(bug->read_mutex); + frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, bytes); + if (frame->datalen < bytes) { + memset(((unsigned char *)frame->data) + frame->datalen, 0, bytes - frame->datalen); + frame->datalen = bytes; } - - if (wlen) { - switch_mutex_lock(bug->write_mutex); - datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, rdlen); - switch_mutex_unlock(bug->write_mutex); + switch_mutex_unlock(bug->read_mutex); + + switch_mutex_lock(bug->write_mutex); + datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, bytes); + if (datalen < bytes) { + memset(((unsigned char *)bug->data) + datalen, 0, bytes - datalen); + datalen = bytes; } + switch_mutex_unlock(bug->write_mutex); - - bytes = (datalen > frame->datalen) ? datalen : frame->datalen; - switch_assert(bytes <= maxlen); - - if (bytes) { - int16_t *tp = bug->tmp; - - dp = (int16_t *) bug->data; - fp = (int16_t *) frame->data; - rlen = frame->datalen / 2; - wlen = datalen / 2; - blen = bytes / 2; - - if (switch_test_flag(bug, SMBF_STEREO)) { - for (x = 0; x < blen; x++) { - if (x < rlen) { - *(tp++) = *(fp + x); - } else { - *(tp++) = 0; - } - if (x < wlen) { - *(tp++) = *(dp + x); - } else { - *(tp++) = 0; - } + tp = bug->tmp; + dp = (int16_t *) bug->data; + fp = (int16_t *) frame->data; + rlen = frame->datalen / 2; + wlen = datalen / 2; + blen = bytes / 2; + + if (switch_test_flag(bug, SMBF_STEREO)) { + for (x = 0; x < blen; x++) { + if (x < rlen) { + *(tp++) = *(fp + x); + } else { + *(tp++) = 0; } - memcpy(frame->data, bug->tmp, bytes * 2); - } else { - for (x = 0; x < blen; x++) { - int32_t z = 0; - - if (x < rlen) { - z += (int32_t) *(fp + x); - } - if (x < wlen) { - z += (int32_t) *(dp + x); - } - switch_normalize_to_16bit(z); - *(fp + x) = (int16_t) z; + if (x < wlen) { + *(tp++) = *(dp + x); + } else { + *(tp++) = 0; } } + memcpy(frame->data, bug->tmp, bytes * 2); + } else { + for (x = 0; x < blen; x++) { + int32_t z = 0; - frame->datalen = bytes; - frame->samples = bytes / sizeof(int16_t); - frame->rate = read_impl.actual_samples_per_second; - - return SWITCH_STATUS_SUCCESS; + if (x < rlen) { + z += (int32_t) *(fp + x); + } + if (x < wlen) { + z += (int32_t) *(dp + x); + } + switch_normalize_to_16bit(z); + *(fp + x) = (int16_t) z / 2; + } } - return SWITCH_STATUS_FALSE; + frame->datalen = bytes; + frame->samples = bytes / sizeof(int16_t); + frame->rate = read_impl.actual_samples_per_second; + frame->codec = NULL; + + return SWITCH_STATUS_SUCCESS; } #define MAX_BUG_BUFFER 1024 * 512 diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index baf496259d..450399f2b9 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -413,11 +413,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_file_handle_t *fh = (switch_file_handle_t *) user_data; - uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_frame_t frame = { 0 }; - - frame.data = data; - frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; switch (type) { case SWITCH_ABC_TYPE_INIT: @@ -427,11 +422,16 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s switch_core_file_close(fh); } break; - case SWITCH_ABC_TYPE_READ: + case SWITCH_ABC_TYPE_READ_PING: if (fh) { switch_size_t len; switch_core_session_t *session = switch_core_media_bug_get_session(bug); switch_channel_t *channel = switch_core_session_get_channel(session); + uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; + switch_frame_t frame = { 0 }; + + frame.data = data; + frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; if (switch_core_media_bug_read(bug, &frame) == SWITCH_STATUS_SUCCESS) { int doit = 1; @@ -441,7 +441,7 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s if (doit) { len = (switch_size_t) frame.datalen / 2; - switch_core_file_write(fh, frame.data, &len); + switch_core_file_write(fh, data, &len); } } } @@ -482,7 +482,7 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) user_data; uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; switch_frame_t frame = { 0 }; - + frame.data = data; frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; @@ -494,7 +494,7 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data case SWITCH_ABC_TYPE_WRITE: break; case SWITCH_ABC_TYPE_READ_PING: - if (ep->buffer) { + if (ep->buffer) { if (switch_core_media_bug_read(bug, &frame) == SWITCH_STATUS_SUCCESS) { switch_buffer_lock(ep->buffer); switch_buffer_zwrite(ep->buffer, frame.data, frame.datalen); @@ -821,7 +821,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t switch_media_bug_t *bug; switch_status_t status; time_t to = 0; - switch_media_bug_flag_t flags = SMBF_READ_STREAM | SMBF_WRITE_STREAM; + switch_media_bug_flag_t flags = SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_PING; uint8_t channels; switch_codec_implementation_t read_impl = {0}; switch_core_session_get_read_impl(session, &read_impl);