FS-5011 --resolve if you use record_session with a filename with no extension it will record 2 files with that base-name and with extensions -in.XXX and -out.XXX where XXX is the codec name

This commit is contained in:
Anthony Minessale 2013-02-25 16:32:09 -06:00
parent 8987e96744
commit a76b352a1e
6 changed files with 197 additions and 31 deletions

View File

@ -184,6 +184,8 @@ struct switch_media_bug {
switch_frame_t *read_replace_frame_out;
switch_frame_t *write_replace_frame_in;
switch_frame_t *write_replace_frame_out;
switch_frame_t *native_read_frame;
switch_frame_t *native_write_frame;
switch_media_bug_callback_t callback;
switch_mutex_t *read_mutex;
switch_mutex_t *write_mutex;

View File

@ -203,6 +203,11 @@ SWITCH_DECLARE(void *) switch_core_media_bug_get_user_data(_In_ switch_media_bug
*/
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug);
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_native_read_frame(switch_media_bug_t *bug);
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_native_write_frame(switch_media_bug_t *bug);
/*!
\brief Set a return replace frame
\param bug the bug to set the frame on

View File

@ -443,6 +443,8 @@ typedef enum {
SWITCH_ABC_TYPE_WRITE_REPLACE,
SWITCH_ABC_TYPE_READ_REPLACE,
SWITCH_ABC_TYPE_READ_PING,
SWITCH_ABC_TYPE_TAP_NATIVE_READ,
SWITCH_ABC_TYPE_TAP_NATIVE_WRITE,
SWITCH_ABC_TYPE_CLOSE
} switch_abc_type_t;
@ -1498,7 +1500,9 @@ typedef enum {
SMBF_PRUNE = (1 << 8),
SMBF_NO_PAUSE = (1 << 9),
SMBF_STEREO_SWAP = (1 << 10),
SMBF_LOCK = (1 << 11)
SMBF_LOCK = (1 << 11),
SMBF_TAP_NATIVE_READ = (1 << 12),
SMBF_TAP_NATIVE_WRITE = (1 << 13)
} switch_media_bug_flag_enum_t;
typedef uint32_t switch_media_bug_flag_t;

View File

@ -221,7 +221,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
status = SWITCH_STATUS_FALSE;
goto even_more_done;
}
}
if (status != SWITCH_STATUS_SUCCESS) {
@ -247,6 +246,49 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
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) {
@ -257,11 +299,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
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 */
@ -769,6 +806,50 @@ static switch_status_t perform_write(switch_core_session_t *session, switch_fram
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) {
@ -872,11 +953,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
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;

View File

@ -103,6 +103,16 @@ SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_read_replace_frame(sw
return bug->read_replace_frame_in;
}
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_native_read_frame(switch_media_bug_t *bug)
{
return bug->native_read_frame;
}
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_native_write_frame(switch_media_bug_t *bug)
{
return bug->native_write_frame;
}
SWITCH_DECLARE(void) switch_core_media_bug_set_read_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame)
{
bug->read_replace_frame_out = frame;

View File

@ -1078,6 +1078,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_
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;
@ -1089,7 +1092,8 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
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:
@ -1099,6 +1103,22 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
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:
{
@ -1110,7 +1130,10 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
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 };
@ -1150,7 +1173,7 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
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, ':'))) {
@ -1196,8 +1219,6 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
return SWITCH_FALSE;
}
}
}
break;
case SWITCH_ABC_TYPE_WRITE:
@ -1739,6 +1760,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t
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);
@ -1889,7 +1912,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t
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) {
@ -1902,49 +1925,96 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t
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);
}
@ -1952,7 +2022,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t
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;