mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-04 12:12:48 +00:00
I thought I was going to be able to leave 1.4 alone, but that was not the case.
I ran into some problems with G.722 in 1.4, so I have merged in all of the fixes in this area that I have made in trunk/1.6.0, and things are happy again. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@114550 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -102,6 +102,9 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
s->fr.datalen = res;
|
s->fr.datalen = res;
|
||||||
|
if (s->fmt->format == AST_FORMAT_G722)
|
||||||
|
*whennext = s->fr.samples = res * 2;
|
||||||
|
else
|
||||||
*whennext = s->fr.samples = res;
|
*whennext = s->fr.samples = res;
|
||||||
return &s->fr;
|
return &s->fr;
|
||||||
}
|
}
|
||||||
@@ -380,24 +383,31 @@ static int au_rewrite(struct ast_filestream *s, const char *comment)
|
|||||||
static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
|
static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
|
||||||
{
|
{
|
||||||
off_t min, max, cur;
|
off_t min, max, cur;
|
||||||
long offset = 0, samples;
|
long offset = 0, bytes;
|
||||||
|
|
||||||
|
if (fs->fmt->format == AST_FORMAT_G722)
|
||||||
|
bytes = sample_offset / 2;
|
||||||
|
else
|
||||||
|
bytes = sample_offset;
|
||||||
|
|
||||||
samples = sample_offset;
|
|
||||||
min = AU_HEADER_SIZE;
|
min = AU_HEADER_SIZE;
|
||||||
cur = ftello(fs->f);
|
cur = ftello(fs->f);
|
||||||
fseek(fs->f, 0, SEEK_END);
|
fseek(fs->f, 0, SEEK_END);
|
||||||
max = ftello(fs->f);
|
max = ftello(fs->f);
|
||||||
|
|
||||||
if (whence == SEEK_SET)
|
if (whence == SEEK_SET)
|
||||||
offset = samples + min;
|
offset = bytes + min;
|
||||||
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
|
||||||
offset = samples + cur;
|
offset = bytes + cur;
|
||||||
else if (whence == SEEK_END)
|
else if (whence == SEEK_END)
|
||||||
offset = max - samples;
|
offset = max - bytes;
|
||||||
if (whence != SEEK_FORCECUR) {
|
if (whence != SEEK_FORCECUR) {
|
||||||
offset = (offset > max) ? max : offset;
|
offset = (offset > max) ? max : offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* always protect the header space. */
|
/* always protect the header space. */
|
||||||
offset = (offset < min) ? min : offset;
|
offset = (offset < min) ? min : offset;
|
||||||
|
|
||||||
return fseeko(fs->f, offset, SEEK_SET);
|
return fseeko(fs->f, offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1573,7 +1573,7 @@ static int generator_force(const void *data)
|
|||||||
if (!tmp || !generate)
|
if (!tmp || !generate)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
res = generate(chan, tmp, 0, 160);
|
res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
|
||||||
|
|
||||||
chan->generatordata = tmp;
|
chan->generatordata = tmp;
|
||||||
|
|
||||||
@@ -1889,6 +1889,7 @@ static void ast_read_generator_actions(struct ast_channel *chan, struct ast_fram
|
|||||||
void *tmp = chan->generatordata;
|
void *tmp = chan->generatordata;
|
||||||
int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
|
int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
|
||||||
int res;
|
int res;
|
||||||
|
int samples;
|
||||||
|
|
||||||
if (chan->timingfunc) {
|
if (chan->timingfunc) {
|
||||||
if (option_debug > 1)
|
if (option_debug > 1)
|
||||||
@@ -1897,6 +1898,15 @@ static void ast_read_generator_actions(struct ast_channel *chan, struct ast_fram
|
|||||||
}
|
}
|
||||||
|
|
||||||
chan->generatordata = NULL; /* reset, to let writes go through */
|
chan->generatordata = NULL; /* reset, to let writes go through */
|
||||||
|
|
||||||
|
if (f->subclass != chan->writeformat) {
|
||||||
|
float factor;
|
||||||
|
factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass));
|
||||||
|
samples = (int) ( ((float) f->samples) * factor );
|
||||||
|
} else {
|
||||||
|
samples = f->samples;
|
||||||
|
}
|
||||||
|
|
||||||
if (chan->generator->generate) {
|
if (chan->generator->generate) {
|
||||||
generate = chan->generator->generate;
|
generate = chan->generator->generate;
|
||||||
}
|
}
|
||||||
@@ -1909,7 +1919,7 @@ static void ast_read_generator_actions(struct ast_channel *chan, struct ast_fram
|
|||||||
* avoidance not to work in deeper functions
|
* avoidance not to work in deeper functions
|
||||||
*/
|
*/
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
res = generate(chan, tmp, f->datalen, f->samples);
|
res = generate(chan, tmp, f->datalen, samples);
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
chan->generatordata = tmp;
|
chan->generatordata = tmp;
|
||||||
if (res) {
|
if (res) {
|
||||||
|
21
main/file.c
21
main/file.c
@@ -680,11 +680,21 @@ static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
|
|||||||
}
|
}
|
||||||
if (whennext != s->lasttimeout) {
|
if (whennext != s->lasttimeout) {
|
||||||
#ifdef HAVE_ZAPTEL
|
#ifdef HAVE_ZAPTEL
|
||||||
if (s->owner->timingfd > -1)
|
if (s->owner->timingfd > -1) {
|
||||||
ast_settimeout(s->owner, whennext, ast_fsread_audio, s);
|
int zap_timer_samples = whennext;
|
||||||
else
|
int rate;
|
||||||
|
/* whennext is in samples, but zaptel timers operate in 8 kHz samples. */
|
||||||
|
if ((rate = ast_format_rate(s->fmt->format)) != 8000) {
|
||||||
|
float factor;
|
||||||
|
factor = ((float) rate) / ((float) 8000.0);
|
||||||
|
zap_timer_samples = (int) ( ((float) zap_timer_samples) / factor );
|
||||||
|
}
|
||||||
|
ast_settimeout(s->owner, zap_timer_samples, ast_fsread_audio, s);
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_fsread_audio, s);
|
s->owner->streamid = ast_sched_add(s->owner->sched,
|
||||||
|
whennext / (ast_format_rate(s->fmt->format) / 1000),
|
||||||
|
ast_fsread_audio, s);
|
||||||
s->lasttimeout = whennext;
|
s->lasttimeout = whennext;
|
||||||
return FSREAD_SUCCESS_NOSCHED;
|
return FSREAD_SUCCESS_NOSCHED;
|
||||||
}
|
}
|
||||||
@@ -728,7 +738,8 @@ static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (whennext != s->lasttimeout) {
|
if (whennext != s->lasttimeout) {
|
||||||
s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext / 8,
|
s->owner->vstreamid = ast_sched_add(s->owner->sched,
|
||||||
|
whennext / (ast_format_rate(s->fmt->format) / 1000),
|
||||||
ast_fsread_video, s);
|
ast_fsread_video, s);
|
||||||
s->lasttimeout = whennext;
|
s->lasttimeout = whennext;
|
||||||
return FSREAD_SUCCESS_NOSCHED;
|
return FSREAD_SUCCESS_NOSCHED;
|
||||||
|
17
main/rtp.c
17
main/rtp.c
@@ -1313,7 +1313,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
|
|||||||
/* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
|
/* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
|
||||||
ast_set_flag(&rtp->f, AST_FRFLAG_HAS_TIMING_INFO);
|
ast_set_flag(&rtp->f, AST_FRFLAG_HAS_TIMING_INFO);
|
||||||
rtp->f.ts = timestamp / 8;
|
rtp->f.ts = timestamp / 8;
|
||||||
rtp->f.len = rtp->f.samples / ( (ast_format_rate(rtp->f.subclass) == 16000) ? 16 : 8 );
|
rtp->f.len = rtp->f.samples / (ast_format_rate(rtp->f.subclass) / 1000);
|
||||||
} else {
|
} else {
|
||||||
/* Video -- samples is # of samples vs. 90000 */
|
/* Video -- samples is # of samples vs. 90000 */
|
||||||
if (!rtp->lastividtimestamp)
|
if (!rtp->lastividtimestamp)
|
||||||
@@ -2795,8 +2795,14 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
|
|||||||
ast_smoother_feed(rtp->smoother, _f);
|
ast_smoother_feed(rtp->smoother, _f);
|
||||||
}
|
}
|
||||||
|
|
||||||
while((f = ast_smoother_read(rtp->smoother)) && (f->data))
|
while ((f = ast_smoother_read(rtp->smoother)) && (f->data)) {
|
||||||
|
if (f->subclass == AST_FORMAT_G722) {
|
||||||
|
/* G.722 is silllllllllllllly */
|
||||||
|
f->samples /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
ast_rtp_raw_write(rtp, f, codec);
|
ast_rtp_raw_write(rtp, f, codec);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Don't buffer outgoing frames; send them one-per-packet: */
|
/* Don't buffer outgoing frames; send them one-per-packet: */
|
||||||
if (_f->offset < hdrlen) {
|
if (_f->offset < hdrlen) {
|
||||||
@@ -2804,8 +2810,13 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
|
|||||||
} else {
|
} else {
|
||||||
f = _f;
|
f = _f;
|
||||||
}
|
}
|
||||||
if (f->data)
|
if (f->data) {
|
||||||
|
if (f->subclass == AST_FORMAT_G722) {
|
||||||
|
/* G.722 is silllllllllllllly */
|
||||||
|
f->samples /= 2;
|
||||||
|
}
|
||||||
ast_rtp_raw_write(rtp, f, codec);
|
ast_rtp_raw_write(rtp, f, codec);
|
||||||
|
}
|
||||||
if (f != _f)
|
if (f != _f)
|
||||||
ast_frfree(f);
|
ast_frfree(f);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user