diff options
-rwxr-xr-x | channel.c | 51 | ||||
-rwxr-xr-x | formats/format_g729.c | 12 | ||||
-rwxr-xr-x | formats/format_gsm.c | 10 | ||||
-rwxr-xr-x | formats/format_mp3.c | 3 | ||||
-rwxr-xr-x | formats/format_pcm.c | 12 | ||||
-rwxr-xr-x | formats/format_pcm_alaw.c | 12 | ||||
-rwxr-xr-x | formats/format_wav.c | 14 | ||||
-rwxr-xr-x | formats/format_wav_gsm.c | 10 | ||||
-rwxr-xr-x | include/asterisk/channel.h | 4 | ||||
-rwxr-xr-x | include/asterisk/file.h | 2 |
10 files changed, 92 insertions, 38 deletions
@@ -39,6 +39,11 @@ #include <linux/zaptel.h> #endif +/* uncomment if you have problems with 'monitoring' synchronized files */ +#if 0 +#define MONITOR_CONSTANT_DELAY +#define MONITOR_DELAY 150 * 8 /* 150 ms of MONITORING DELAY */ +#endif static int shutting_down = 0; static int uniqueint = 0; @@ -1088,9 +1093,25 @@ struct ast_frame *ast_read(struct ast_channel *chan) f = &null_frame; } else { if (chan->monitor && chan->monitor->read_stream ) { - if( ast_writestream( chan->monitor->read_stream, f ) < 0 ) { +#ifndef MONITOR_CONSTANT_DELAY + int jump = chan->outsmpl - chan->insmpl - 2 * f->samples; + if (jump >= 0) { + if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) + ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); + chan->insmpl += jump + 2 * f->samples; + } else + chan->insmpl+= f->samples; +#else + int jump = chan->outsmpl - chan->insmpl; + if (jump - MONITOR_DELAY >= 0) { + if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) + ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); + chan->insmpl += jump; + } else + chan->insmpl += f->samples; +#endif + if (ast_writestream(chan->monitor->read_stream, f) < 0) ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); - } } if (chan->pvt->readtrans) { f = ast_translate(chan->pvt->readtrans, f, 1); @@ -1360,18 +1381,32 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr) f = ast_translate(chan->pvt->writetrans, fr, 0); } else f = fr; - if (f) - { + if (f) { res = chan->pvt->write(chan, f); if( chan->monitor && chan->monitor->write_stream && f && ( f->frametype == AST_FRAME_VOICE ) ) { - if( ast_writestream( chan->monitor->write_stream, f ) < 0 ) { +#ifndef MONITOR_CONSTANT_DELAY + int jump = chan->insmpl - chan->outsmpl - 2 * f->samples; + if (jump >= 0) { + if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) + ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); + chan->outsmpl += jump + 2 * f->samples; + } else + chan->outsmpl += f->samples; +#else + int jump = chan->insmpl - chan->outsmpl; + if (jump - MONITOR_DELAY >= 0) { + if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) + ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); + chan->outsmpl += jump; + } else + chan->outsmpl += f->samples; +#endif + if (ast_writestream(chan->monitor->write_stream, f) < 0) ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); - } } - } - else + } else res = 0; } } diff --git a/formats/format_g729.c b/formats/format_g729.c index b35ff966f..23a3c5a6d 100755 --- a/formats/format_g729.c +++ b/formats/format_g729.c @@ -174,14 +174,16 @@ static int g729_seek(struct ast_filestream *fs, long sample_offset, int whence) max = lseek(fs->fd, 0, SEEK_END); bytes = 20 * (sample_offset / 160); - if(whence == SEEK_SET) + if (whence == SEEK_SET) offset = bytes; - if(whence == SEEK_CUR) + else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) offset = cur + bytes; - if(whence == SEEK_END) + else if (whence == SEEK_END) offset = max - bytes; - offset = (offset > max)?max:offset; - offset = (offset < min)?min:offset; + if (whence != SEEK_FORCECUR) { + offset = (offset > max)?max:offset; + offset = (offset < min)?min:offset; + } if (lseek(fs->fd, offset, SEEK_SET) < 0) return -1; return 0; diff --git a/formats/format_gsm.c b/formats/format_gsm.c index 078d79d33..ad39c0a0f 100755 --- a/formats/format_gsm.c +++ b/formats/format_gsm.c @@ -185,12 +185,14 @@ static int gsm_seek(struct ast_filestream *fs, long sample_offset, int whence) distance = (sample_offset/160) * 33; if(whence == SEEK_SET) offset = distance; - if(whence == SEEK_CUR) + else if(whence == SEEK_CUR || whence == SEEK_FORCECUR) offset = distance + cur; - if(whence == SEEK_END) + else if(whence == SEEK_END) offset = max - distance; - offset = (offset > max)?max:offset; - offset = (offset < min)?min:offset; + if (whence != SEEK_FORCECUR) { + offset = (offset > max)?max:offset; + offset = (offset < min)?min:offset; + } return lseek(fs->fd, offset, SEEK_SET); } diff --git a/formats/format_mp3.c b/formats/format_mp3.c index bff51d686..832110e67 100755 --- a/formats/format_mp3.c +++ b/formats/format_mp3.c @@ -41,8 +41,9 @@ struct ast_filestream { struct timeval last; }; - +#if 0 static struct ast_filestream *glist = NULL; +#endif static ast_mutex_t mp3_lock = AST_MUTEX_INITIALIZER; static int glistcnt = 0; diff --git a/formats/format_pcm.c b/formats/format_pcm.c index ebc9bf87a..038de171d 100755 --- a/formats/format_pcm.c +++ b/formats/format_pcm.c @@ -163,14 +163,16 @@ static int pcm_seek(struct ast_filestream *fs, long sample_offset, int whence) min = 0; cur = lseek(fs->fd, 0, SEEK_CUR); max = lseek(fs->fd, 0, SEEK_END); - if(whence == SEEK_SET) + if (whence == SEEK_SET) offset = sample_offset; - if(whence == SEEK_CUR) + else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) offset = sample_offset + cur; - if(whence == SEEK_END) + else if (whence == SEEK_END) offset = max - sample_offset; - offset = (offset > max)?max:offset; - offset = (offset < min)?min:offset; + if (whence != SEEK_FORCECUR) { + offset = (offset > max)?max:offset; + offset = (offset < min)?min:offset; + } return lseek(fs->fd, offset, SEEK_SET); } diff --git a/formats/format_pcm_alaw.c b/formats/format_pcm_alaw.c index 8e96b41af..54d79bb29 100755 --- a/formats/format_pcm_alaw.c +++ b/formats/format_pcm_alaw.c @@ -242,14 +242,16 @@ static int pcm_seek(struct ast_filestream *fs, long sample_offset, int whence) min = 0; cur = lseek(fs->fd, 0, SEEK_CUR); max = lseek(fs->fd, 0, SEEK_END); - if(whence == SEEK_SET) + if (whence == SEEK_SET) offset = sample_offset; - if(whence == SEEK_CUR) + else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) offset = sample_offset + cur; - if(whence == SEEK_END) + else if (whence == SEEK_END) offset = max - sample_offset; - offset = (offset > max)?max:offset; - offset = (offset < min)?min:offset; + if (whence != SEEK_FORCECUR) { + offset = (offset > max)?max:offset; + offset = (offset < min)?min:offset; + } return lseek(fs->fd, offset, SEEK_SET); } diff --git a/formats/format_wav.c b/formats/format_wav.c index 3771df354..2a549b710 100755 --- a/formats/format_wav.c +++ b/formats/format_wav.c @@ -499,14 +499,16 @@ static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence) min = 44; /* wav header is 44 bytes */ cur = lseek(fs->fd, 0, SEEK_CUR); max = lseek(fs->fd, 0, SEEK_END); - if(whence == SEEK_SET) + if (whence == SEEK_SET) offset = samples + min; - if(whence == SEEK_CUR) + else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) offset = samples + cur; - if(whence == SEEK_END) - offset = max - samples; - offset = (offset > max)?max:offset; - offset = (offset < min)?min:offset; + else if (whence == SEEK_END) + offset = max - samples; + if (whence != SEEK_FORCECUR) { + offset = (offset > max)?max:offset; + offset = (offset < min)?min:offset; + } return lseek(fs->fd,offset,SEEK_SET); } diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c index fbb97d6ab..55a607d2f 100755 --- a/formats/format_wav_gsm.c +++ b/formats/format_wav_gsm.c @@ -478,12 +478,14 @@ static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence) distance = (sample_offset/320) * 65; if(whence == SEEK_SET) offset = distance + min; - if(whence == SEEK_CUR) + else if(whence == SEEK_CUR || whence == SEEK_FORCECUR) offset = distance + cur; - if(whence == SEEK_END) + else if(whence == SEEK_END) offset = max - distance; - offset = (offset < min)?min:offset; - offset = (offset > max)?max:offset; + if (whence != SEEK_FORCECUR) { + offset = (offset < min)?min:offset; + offset = (offset > max)?max:offset; + } fs->secondhalf = 0; return lseek(fs->fd, offset, SEEK_SET); } diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 7cd2470e0..5a39a6743 100755 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -199,6 +199,10 @@ struct ast_channel { /* Channel monitoring */ struct ast_channel_monitor *monitor; + /*! Track the read/written samples for monitor use */ + unsigned long insmpl; + unsigned long outsmpl; + /* Frames in/out counters */ unsigned int fin; unsigned int fout; diff --git a/include/asterisk/file.h b/include/asterisk/file.h index da3723dac..f7808e435 100755 --- a/include/asterisk/file.h +++ b/include/asterisk/file.h @@ -27,6 +27,8 @@ extern "C" { //! Convenient for waiting #define AST_DIGIT_ANY "0123456789#*" +#define SEEK_FORCECUR 10 + /* Defined by individual formats. First item MUST be a pointer for use by the stream manager */ struct ast_filestream; |