mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-20 12:20:12 +00:00
Fix synchronization of recorded files when using Monitor application
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1446 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
51
channel.c
51
channel.c
@@ -39,6 +39,11 @@
|
|||||||
#include <linux/zaptel.h>
|
#include <linux/zaptel.h>
|
||||||
#endif
|
#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 shutting_down = 0;
|
||||||
static int uniqueint = 0;
|
static int uniqueint = 0;
|
||||||
@@ -1088,9 +1093,25 @@ struct ast_frame *ast_read(struct ast_channel *chan)
|
|||||||
f = &null_frame;
|
f = &null_frame;
|
||||||
} else {
|
} else {
|
||||||
if (chan->monitor && chan->monitor->read_stream ) {
|
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");
|
ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (chan->pvt->readtrans) {
|
if (chan->pvt->readtrans) {
|
||||||
f = ast_translate(chan->pvt->readtrans, f, 1);
|
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);
|
f = ast_translate(chan->pvt->writetrans, fr, 0);
|
||||||
} else
|
} else
|
||||||
f = fr;
|
f = fr;
|
||||||
if (f)
|
if (f) {
|
||||||
{
|
|
||||||
res = chan->pvt->write(chan, f);
|
res = chan->pvt->write(chan, f);
|
||||||
if( chan->monitor &&
|
if( chan->monitor &&
|
||||||
chan->monitor->write_stream &&
|
chan->monitor->write_stream &&
|
||||||
f && ( f->frametype == AST_FRAME_VOICE ) ) {
|
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");
|
ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -174,14 +174,16 @@ static int g729_seek(struct ast_filestream *fs, long sample_offset, int whence)
|
|||||||
max = lseek(fs->fd, 0, SEEK_END);
|
max = lseek(fs->fd, 0, SEEK_END);
|
||||||
|
|
||||||
bytes = 20 * (sample_offset / 160);
|
bytes = 20 * (sample_offset / 160);
|
||||||
if(whence == SEEK_SET)
|
if (whence == SEEK_SET)
|
||||||
offset = bytes;
|
offset = bytes;
|
||||||
if(whence == SEEK_CUR)
|
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
||||||
offset = cur + bytes;
|
offset = cur + bytes;
|
||||||
if(whence == SEEK_END)
|
else if (whence == SEEK_END)
|
||||||
offset = max - bytes;
|
offset = max - bytes;
|
||||||
offset = (offset > max)?max:offset;
|
if (whence != SEEK_FORCECUR) {
|
||||||
offset = (offset < min)?min:offset;
|
offset = (offset > max)?max:offset;
|
||||||
|
offset = (offset < min)?min:offset;
|
||||||
|
}
|
||||||
if (lseek(fs->fd, offset, SEEK_SET) < 0)
|
if (lseek(fs->fd, offset, SEEK_SET) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -185,12 +185,14 @@ static int gsm_seek(struct ast_filestream *fs, long sample_offset, int whence)
|
|||||||
distance = (sample_offset/160) * 33;
|
distance = (sample_offset/160) * 33;
|
||||||
if(whence == SEEK_SET)
|
if(whence == SEEK_SET)
|
||||||
offset = distance;
|
offset = distance;
|
||||||
if(whence == SEEK_CUR)
|
else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
||||||
offset = distance + cur;
|
offset = distance + cur;
|
||||||
if(whence == SEEK_END)
|
else if(whence == SEEK_END)
|
||||||
offset = max - distance;
|
offset = max - distance;
|
||||||
offset = (offset > max)?max:offset;
|
if (whence != SEEK_FORCECUR) {
|
||||||
offset = (offset < min)?min:offset;
|
offset = (offset > max)?max:offset;
|
||||||
|
offset = (offset < min)?min:offset;
|
||||||
|
}
|
||||||
return lseek(fs->fd, offset, SEEK_SET);
|
return lseek(fs->fd, offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,8 +41,9 @@ struct ast_filestream {
|
|||||||
struct timeval last;
|
struct timeval last;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
static struct ast_filestream *glist = NULL;
|
static struct ast_filestream *glist = NULL;
|
||||||
|
#endif
|
||||||
static ast_mutex_t mp3_lock = AST_MUTEX_INITIALIZER;
|
static ast_mutex_t mp3_lock = AST_MUTEX_INITIALIZER;
|
||||||
static int glistcnt = 0;
|
static int glistcnt = 0;
|
||||||
|
|
||||||
|
@@ -163,14 +163,16 @@ static int pcm_seek(struct ast_filestream *fs, long sample_offset, int whence)
|
|||||||
min = 0;
|
min = 0;
|
||||||
cur = lseek(fs->fd, 0, SEEK_CUR);
|
cur = lseek(fs->fd, 0, SEEK_CUR);
|
||||||
max = lseek(fs->fd, 0, SEEK_END);
|
max = lseek(fs->fd, 0, SEEK_END);
|
||||||
if(whence == SEEK_SET)
|
if (whence == SEEK_SET)
|
||||||
offset = sample_offset;
|
offset = sample_offset;
|
||||||
if(whence == SEEK_CUR)
|
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
||||||
offset = sample_offset + cur;
|
offset = sample_offset + cur;
|
||||||
if(whence == SEEK_END)
|
else if (whence == SEEK_END)
|
||||||
offset = max - sample_offset;
|
offset = max - sample_offset;
|
||||||
offset = (offset > max)?max:offset;
|
if (whence != SEEK_FORCECUR) {
|
||||||
offset = (offset < min)?min:offset;
|
offset = (offset > max)?max:offset;
|
||||||
|
offset = (offset < min)?min:offset;
|
||||||
|
}
|
||||||
return lseek(fs->fd, offset, SEEK_SET);
|
return lseek(fs->fd, offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -242,14 +242,16 @@ static int pcm_seek(struct ast_filestream *fs, long sample_offset, int whence)
|
|||||||
min = 0;
|
min = 0;
|
||||||
cur = lseek(fs->fd, 0, SEEK_CUR);
|
cur = lseek(fs->fd, 0, SEEK_CUR);
|
||||||
max = lseek(fs->fd, 0, SEEK_END);
|
max = lseek(fs->fd, 0, SEEK_END);
|
||||||
if(whence == SEEK_SET)
|
if (whence == SEEK_SET)
|
||||||
offset = sample_offset;
|
offset = sample_offset;
|
||||||
if(whence == SEEK_CUR)
|
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
||||||
offset = sample_offset + cur;
|
offset = sample_offset + cur;
|
||||||
if(whence == SEEK_END)
|
else if (whence == SEEK_END)
|
||||||
offset = max - sample_offset;
|
offset = max - sample_offset;
|
||||||
offset = (offset > max)?max:offset;
|
if (whence != SEEK_FORCECUR) {
|
||||||
offset = (offset < min)?min:offset;
|
offset = (offset > max)?max:offset;
|
||||||
|
offset = (offset < min)?min:offset;
|
||||||
|
}
|
||||||
return lseek(fs->fd, offset, SEEK_SET);
|
return lseek(fs->fd, offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -499,14 +499,16 @@ static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence)
|
|||||||
min = 44; /* wav header is 44 bytes */
|
min = 44; /* wav header is 44 bytes */
|
||||||
cur = lseek(fs->fd, 0, SEEK_CUR);
|
cur = lseek(fs->fd, 0, SEEK_CUR);
|
||||||
max = lseek(fs->fd, 0, SEEK_END);
|
max = lseek(fs->fd, 0, SEEK_END);
|
||||||
if(whence == SEEK_SET)
|
if (whence == SEEK_SET)
|
||||||
offset = samples + min;
|
offset = samples + min;
|
||||||
if(whence == SEEK_CUR)
|
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
||||||
offset = samples + cur;
|
offset = samples + cur;
|
||||||
if(whence == SEEK_END)
|
else if (whence == SEEK_END)
|
||||||
offset = max - samples;
|
offset = max - samples;
|
||||||
offset = (offset > max)?max:offset;
|
if (whence != SEEK_FORCECUR) {
|
||||||
offset = (offset < min)?min:offset;
|
offset = (offset > max)?max:offset;
|
||||||
|
offset = (offset < min)?min:offset;
|
||||||
|
}
|
||||||
return lseek(fs->fd,offset,SEEK_SET);
|
return lseek(fs->fd,offset,SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -478,12 +478,14 @@ static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence)
|
|||||||
distance = (sample_offset/320) * 65;
|
distance = (sample_offset/320) * 65;
|
||||||
if(whence == SEEK_SET)
|
if(whence == SEEK_SET)
|
||||||
offset = distance + min;
|
offset = distance + min;
|
||||||
if(whence == SEEK_CUR)
|
else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
||||||
offset = distance + cur;
|
offset = distance + cur;
|
||||||
if(whence == SEEK_END)
|
else if(whence == SEEK_END)
|
||||||
offset = max - distance;
|
offset = max - distance;
|
||||||
offset = (offset < min)?min:offset;
|
if (whence != SEEK_FORCECUR) {
|
||||||
offset = (offset > max)?max:offset;
|
offset = (offset < min)?min:offset;
|
||||||
|
offset = (offset > max)?max:offset;
|
||||||
|
}
|
||||||
fs->secondhalf = 0;
|
fs->secondhalf = 0;
|
||||||
return lseek(fs->fd, offset, SEEK_SET);
|
return lseek(fs->fd, offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
@@ -199,6 +199,10 @@ struct ast_channel {
|
|||||||
/* Channel monitoring */
|
/* Channel monitoring */
|
||||||
struct ast_channel_monitor *monitor;
|
struct ast_channel_monitor *monitor;
|
||||||
|
|
||||||
|
/*! Track the read/written samples for monitor use */
|
||||||
|
unsigned long insmpl;
|
||||||
|
unsigned long outsmpl;
|
||||||
|
|
||||||
/* Frames in/out counters */
|
/* Frames in/out counters */
|
||||||
unsigned int fin;
|
unsigned int fin;
|
||||||
unsigned int fout;
|
unsigned int fout;
|
||||||
|
@@ -27,6 +27,8 @@ extern "C" {
|
|||||||
//! Convenient for waiting
|
//! Convenient for waiting
|
||||||
#define AST_DIGIT_ANY "0123456789#*"
|
#define AST_DIGIT_ANY "0123456789#*"
|
||||||
|
|
||||||
|
#define SEEK_FORCECUR 10
|
||||||
|
|
||||||
/* Defined by individual formats. First item MUST be a
|
/* Defined by individual formats. First item MUST be a
|
||||||
pointer for use by the stream manager */
|
pointer for use by the stream manager */
|
||||||
struct ast_filestream;
|
struct ast_filestream;
|
||||||
|
Reference in New Issue
Block a user