]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-5011 --resolve if you use record_session with a filename with no extension it...
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 25 Feb 2013 22:32:09 +0000 (16:32 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 25 Feb 2013 22:32:09 +0000 (16:32 -0600)
src/include/private/switch_core_pvt.h
src/include/switch_core.h
src/include/switch_types.h
src/switch_core_io.c
src/switch_core_media_bug.c
src/switch_ivr_async.c

index e4e8dc7c6f4b161842d4a8800474f2928a888ce0..60240e646d1fc5019ca6162e5c9a07bdf4f11534 100644 (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;
index e3f5634ce4c5a95958f5d92af078d4f61419d4f8..3383b67bc00c8432a70df6d356119da4891def6a 100644 (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
index 5fa7c158f068db50a69b1e3f126a3ccd6f23d944..2c8b9503cf7b619ca7c5f388da74e68308dc67da 100644 (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;
 
index effb500e04289513af455b4cc0d8c578bff0b4af..22e0cc811db392da370e4f9912f5a27f184b3dff 100644 (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;
index 7beb04815551c3f034cc2d0577e29686bb274961..938d9b5996e703ae616e178e7a9b4c68b388723c 100644 (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;
index 80d945f875505162d5be03fd500369b4321069d5..8b1ce552d497048a2ead0ea09575c87716c82200 100644 (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;