fix double close of filehandles and add recording of native files

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11108 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-01-10 03:52:28 +00:00
parent 732677a58f
commit c711a50846
3 changed files with 75 additions and 35 deletions

View File

@ -251,7 +251,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
done:
if (fh.file_interface) {
if (switch_test_flag((&fh), SWITCH_FILE_OPEN)) {
switch_core_file_close(&fh);
}

View File

@ -132,7 +132,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh,
{
switch_status_t status = SWITCH_STATUS_FALSE;
switch_size_t want, got, orig_len = *len;
switch_assert(fh != NULL);
switch_assert(fh->file_interface != NULL);
@ -155,19 +155,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh,
if (fh->pre_buffer) {
switch_size_t rlen;
int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
if (!switch_test_flag(fh, SWITCH_FILE_BUFFER_DONE)) {
if (!switch_buffer_inuse(fh->pre_buffer)) {
rlen = fh->pre_buffer_datalen / 2;
rlen = asis ? fh->pre_buffer_datalen : fh->pre_buffer_datalen / 2;
if ((status = fh->file_interface->file_read(fh, fh->pre_buffer_data, &rlen)) != SWITCH_STATUS_SUCCESS || !rlen) {
switch_set_flag(fh, SWITCH_FILE_BUFFER_DONE);
} else {
switch_buffer_write(fh->pre_buffer, fh->pre_buffer_data, rlen * 2);
switch_buffer_write(fh->pre_buffer, fh->pre_buffer_data, asis ? rlen : rlen * 2);
}
}
}
rlen = switch_buffer_read(fh->pre_buffer, data, *len * 2);
*len = rlen / 2;
rlen = switch_buffer_read(fh->pre_buffer, data, asis ? *len : *len * 2);
*len = asis ? rlen : rlen / 2;
if (*len == 0) {
switch_set_flag(fh, SWITCH_FILE_DONE);
@ -277,13 +279,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh,
if (fh->pre_buffer) {
switch_size_t rlen, blen;
switch_status_t status = SWITCH_STATUS_SUCCESS;
int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
switch_buffer_write(fh->pre_buffer, data, *len * 2);
switch_buffer_write(fh->pre_buffer, data, asis ? *len : *len * 2);
rlen = switch_buffer_inuse(fh->pre_buffer);
if (rlen >= fh->pre_buffer_datalen) {
blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen);
blen /= 2;
if (!asis) blen /= 2;
if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) {
*len = 0;
}
@ -345,6 +348,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
switch_assert(fh != NULL);
switch_assert(fh->file_interface != NULL);
if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
return SWITCH_STATUS_FALSE;
}
switch_clear_flag(fh, SWITCH_FILE_OPEN);
status = fh->file_interface->file_close(fh);
@ -355,9 +362,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
if (fh->pre_buffer) {
if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
switch_size_t rlen, blen;
int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
while((rlen = switch_buffer_inuse(fh->pre_buffer))) {
blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen);
blen /= 2;
if (asis) blen /= 2;
if (fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen) != SWITCH_STATUS_SUCCESS) {
break;
}

View File

@ -384,6 +384,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
const char *vval;
time_t start = 0;
uint32_t org_silence_hits = 0;
int asis = 0;
switch_assert(read_codec != NULL);
@ -396,6 +397,30 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
fh->channels = read_codec->implementation->number_of_channels;
fh->native_rate = read_codec->implementation->actual_samples_per_second;
if (!strstr(file, SWITCH_URL_SEPARATOR)) {
char *ext;
const char *prefix;
prefix = switch_channel_get_variable(channel, "sound_prefix");
if (!prefix) {
prefix = SWITCH_GLOBAL_dirs.base_dir;
}
if (!switch_is_file_path(file)) {
file = switch_core_session_sprintf(session, "%s%s%s", prefix, SWITCH_PATH_SEPARATOR, file);
}
if ((ext = strrchr(file, '.'))) {
ext++;
} else {
ext = read_codec->implementation->iananame;
file = switch_core_session_sprintf(session, "%s.%s", file, ext);
asis = 1;
}
}
if (switch_core_file_open(fh,
file,
fh->channels,
@ -444,37 +469,43 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
switch_channel_set_variable(channel, "RECORD_DATE", NULL);
}
codec_name = "L16";
if (switch_core_codec_init(&codec,
codec_name,
NULL,
read_codec->implementation->actual_samples_per_second,
read_codec->implementation->microseconds_per_packet / 1000,
read_codec->implementation->number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
switch_core_session_set_read_codec(session, &codec);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
fh->channels, read_codec->implementation->microseconds_per_packet / 1000);
switch_core_file_close(fh);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
return SWITCH_STATUS_GENERR;
if (!asis) {
codec_name = "L16";
if (switch_core_codec_init(&codec,
codec_name,
NULL,
read_codec->implementation->actual_samples_per_second,
read_codec->implementation->microseconds_per_packet / 1000,
read_codec->implementation->number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
switch_core_session_set_read_codec(session, &codec);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
fh->channels, read_codec->implementation->microseconds_per_packet / 1000);
switch_core_file_close(fh);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
return SWITCH_STATUS_GENERR;
}
}
if (limit) {
start = switch_timestamp(NULL);
}
if (fh->thresh) {
if (fh->silence_hits) {
fh->silence_hits = fh->samplerate * fh->silence_hits / read_codec->implementation->samples_per_packet;
if (asis) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't detect silence on a native recording.\n");
} else {
fh->silence_hits = fh->samplerate * 3 / read_codec->implementation->samples_per_packet;
if (fh->silence_hits) {
fh->silence_hits = fh->samplerate * fh->silence_hits / read_codec->implementation->samples_per_packet;
} else {
fh->silence_hits = fh->samplerate * 3 / read_codec->implementation->samples_per_packet;
}
org_silence_hits = fh->silence_hits;
}
org_silence_hits = fh->silence_hits;
}
for (;;) {
@ -543,7 +574,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
}
}
if (fh->thresh) {
if (!asis && fh->thresh) {
int16_t *fdata = (int16_t *) read_frame->data;
uint32_t samples = read_frame->datalen / sizeof(*fdata);
uint32_t score, count = 0, j = 0;
@ -571,8 +602,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
int16_t *data = read_frame->data;
len = (switch_size_t) read_frame->datalen / 2;
len = (switch_size_t) asis ? read_frame->datalen : read_frame->datalen / 2;
if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
break;
}