status = SWITCH_STATUS_FALSE;
goto even_more_done;
}
-
}
if (status != SWITCH_STATUS_SUCCESS) {
goto done;
}
+
+ if (session->bugs && !((*frame)->flags & SFF_NOT_AUDIO) && !((*frame)->flags & SFF_CNG)) {
+ switch_media_bug_t *bp;
+ switch_bool_t ok = SWITCH_TRUE;
+ int prune = 0;
+
+ switch_thread_rwlock_rdlock(session->bug_rwlock);
+
+ for (bp = session->bugs; bp; bp = bp->next) {
+ if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
+ continue;
+ }
+
+ if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
+ continue;
+ }
+ if (switch_test_flag(bp, SMBF_PRUNE)) {
+ prune++;
+ continue;
+ }
+
+ if (bp->ready) {
+ if (switch_test_flag(bp, SMBF_TAP_NATIVE_READ)) {
+ if (bp->callback) {
+ bp->native_read_frame = *frame;
+ ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_TAP_NATIVE_READ);
+ bp->native_read_frame = NULL;
+ }
+ }
+ }
+
+ if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
+ switch_set_flag(bp, SMBF_PRUNE);
+ prune++;
+ }
+ }
+ switch_thread_rwlock_unlock(session->bug_rwlock);
+
+ if (prune) {
+ switch_core_media_bug_prune(session);
+ }
+ }
+
codec_impl = *(*frame)->codec->implementation;
if (session->read_codec->implementation->impl_id != codec_impl.impl_id) {
do_resample = 1;
}
- if (session->bugs && !need_codec) {
- do_bugs = 1;
- need_codec = 1;
- }
-
if (switch_test_flag(*frame, SFF_CNG)) {
if (!session->bugs && !session->plc) {
/* Check if other session has bugs */
switch_io_event_hook_write_frame_t *ptr;
switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if (session->bugs && !(frame->flags & SFF_NOT_AUDIO)) {
+ switch_media_bug_t *bp;
+ switch_bool_t ok = SWITCH_TRUE;
+ int prune = 0;
+
+ switch_thread_rwlock_rdlock(session->bug_rwlock);
+
+ for (bp = session->bugs; bp; bp = bp->next) {
+ if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
+ continue;
+ }
+
+ if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
+ continue;
+ }
+ if (switch_test_flag(bp, SMBF_PRUNE)) {
+ prune++;
+ continue;
+ }
+
+ if (bp->ready) {
+ if (switch_test_flag(bp, SMBF_TAP_NATIVE_WRITE)) {
+ if (bp->callback) {
+ bp->native_write_frame = frame;
+ ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_TAP_NATIVE_WRITE);
+ bp->native_write_frame = NULL;
+ }
+ }
+ }
+
+ if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
+ switch_set_flag(bp, SMBF_PRUNE);
+ prune++;
+ }
+ }
+ switch_thread_rwlock_unlock(session->bug_rwlock);
+
+ if (prune) {
+ switch_core_media_bug_prune(session);
+ }
+ }
+
+
if (session->endpoint_interface->io_routines->write_frame) {
if ((status = session->endpoint_interface->io_routines->write_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
need_codec = TRUE;
}
- if (session->bugs && !need_codec) {
- do_bugs = TRUE;
- need_codec = TRUE;
- }
-
if (frame->codec->implementation->actual_samples_per_second != session->write_impl.actual_samples_per_second) {
need_codec = TRUE;
do_resample = TRUE;
struct record_helper {
char *file;
switch_file_handle_t *fh;
+ switch_file_handle_t in_fh;
+ switch_file_handle_t out_fh;
+ int native;
uint32_t packet_len;
int min_sec;
switch_bool_t hangup_on_error;
switch_channel_t *channel = switch_core_session_get_channel(session);
struct record_helper *rh = (struct record_helper *) user_data;
switch_event_t *event;
-
+ switch_frame_t *nframe;
+ switch_size_t len;
switch (type) {
case SWITCH_ABC_TYPE_INIT:
switch_event_fire(&event);
}
+ break;
+ case SWITCH_ABC_TYPE_TAP_NATIVE_READ:
+ {
+ nframe = switch_core_media_bug_get_native_read_frame(bug);
+ len = nframe->datalen;
+ printf("WRITE IN %d\n", nframe->datalen);
+ switch_core_file_write(&rh->in_fh, nframe->data, &len);
+ }
+ break;
+ case SWITCH_ABC_TYPE_TAP_NATIVE_WRITE:
+ {
+ nframe = switch_core_media_bug_get_native_write_frame(bug);
+ printf("WRITE OUT %d\n", nframe->datalen);
+ len = nframe->datalen;
+ switch_core_file_write(&rh->out_fh, nframe->data, &len);
+ }
break;
case SWITCH_ABC_TYPE_CLOSE:
{
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stop recording file %s\n", rh->file);
switch_channel_set_private(channel, rh->file, NULL);
- if (rh->fh) {
+ if (rh->native) {
+ switch_core_file_close(&rh->in_fh);
+ switch_core_file_close(&rh->out_fh);
+ } else if (rh->fh) {
switch_size_t len;
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_frame_t frame = { 0 };
char *cmd = switch_core_session_strdup(session, var);
char *data, *expanded = NULL;
switch_stream_handle_t stream = { 0 };
-
+
SWITCH_STANDARD_STREAM(stream);
if ((data = strchr(cmd, ':'))) {
return SWITCH_FALSE;
}
}
-
-
}
break;
case SWITCH_ABC_TYPE_WRITE:
int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
switch_bool_t hangup_on_error = SWITCH_FALSE;
char *file_path = NULL;
+ char *ext;
+ char *in_file = NULL, *out_file = NULL;
if ((p = switch_channel_get_variable(channel, "RECORD_HANGUP_ON_ERROR"))) {
hangup_on_error = switch_true(p);
if (file_path && !strstr(file_path, SWITCH_URL_SEPARATOR)) {
char *p;
char *path = switch_core_session_strdup(session, file_path);
-
+
if ((p = strrchr(path, *SWITCH_PATH_SEPARATOR))) {
*p = '\0';
if (switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
path = NULL;
}
}
+
+ rh = switch_core_session_alloc(session, sizeof(*rh));
- if (switch_core_file_open(fh, file, channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", file);
- if (hangup_on_error) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ if ((ext = strrchr(file, '.'))) {
+ ext++;
+ if (switch_core_file_open(fh, file, channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", file);
+ if (hangup_on_error) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ }
+ return SWITCH_STATUS_GENERR;
}
- return SWITCH_STATUS_GENERR;
+ } else {
+ int tflags = 0;
+
+ ext = read_impl.iananame;
+
+ in_file = switch_core_session_sprintf(session, "%s-in.%s", file, ext);
+ out_file = switch_core_session_sprintf(session, "%s-out.%s", file, ext);
+
+
+ if (switch_core_file_open(&rh->in_fh, in_file, channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", in_file);
+ if (hangup_on_error) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ }
+ return SWITCH_STATUS_GENERR;
+ }
+
+ if (switch_core_file_open(&rh->out_fh, out_file, channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", out_file);
+ switch_core_file_close(&rh->in_fh);
+ if (hangup_on_error) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ }
+ return SWITCH_STATUS_GENERR;
+ }
+
+ rh->native = 1;
+ fh = NULL;
+
+ if ((flags & SMBF_WRITE_STREAM)) {
+ tflags |= SMBF_TAP_NATIVE_WRITE;
+ }
+
+ if ((flags & SMBF_READ_STREAM)) {
+ tflags |= SMBF_TAP_NATIVE_READ;
+ }
+
+ flags = tflags;
}
+
+
if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) {
vval = (const char *) switch_core_session_strdup(session, p);
- switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval);
+ if (fh) switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval);
switch_channel_set_variable(channel, "RECORD_TITLE", NULL);
}
if ((p = switch_channel_get_variable(channel, "RECORD_COPYRIGHT"))) {
vval = (const char *) switch_core_session_strdup(session, p);
- switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval);
+ if (fh) switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval);
switch_channel_set_variable(channel, "RECORD_COPYRIGHT", NULL);
}
if ((p = switch_channel_get_variable(channel, "RECORD_SOFTWARE"))) {
vval = (const char *) switch_core_session_strdup(session, p);
- switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval);
+ if (fh) switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval);
switch_channel_set_variable(channel, "RECORD_SOFTWARE", NULL);
}
if ((p = switch_channel_get_variable(channel, "RECORD_ARTIST"))) {
vval = (const char *) switch_core_session_strdup(session, p);
- switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval);
+ if (fh) switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval);
switch_channel_set_variable(channel, "RECORD_ARTIST", NULL);
}
if ((p = switch_channel_get_variable(channel, "RECORD_COMMENT"))) {
vval = (const char *) switch_core_session_strdup(session, p);
- switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval);
+ if (fh) switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval);
switch_channel_set_variable(channel, "RECORD_COMMENT", NULL);
}
if ((p = switch_channel_get_variable(channel, "RECORD_DATE"))) {
vval = (const char *) switch_core_session_strdup(session, p);
- switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval);
+ if (fh) switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval);
switch_channel_set_variable(channel, "RECORD_DATE", NULL);
}
to = switch_epoch_time_now(NULL) + limit;
}
- rh = switch_core_session_alloc(session, sizeof(*rh));
rh->fh = fh;
rh->file = switch_core_session_strdup(session, file);
rh->packet_len = read_impl.decoded_bytes_per_packet;