aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-03-07 00:25:48 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-03-07 00:25:48 +0000
commit98779a7456ecc7b0e71e78c0e91079d3002f165a (patch)
treeb4103a6af6e12c3f9e62ffd319e99da8eb6c970d
parent2f5ff32fe410423a32e746cfe2500cce8fc8c333 (diff)
Merged revisions 106501 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r106501 | russell | 2008-03-06 18:24:58 -0600 (Thu, 06 Mar 2008) | 28 lines Merge changes from team/russell/g722-sillyness ... Fix a number of other places where the number of samples in a G722 frame was not properly handled because of various reasons. main/rtp.c: - When a G722 frame is read from the smoother, the number of samples in the frame must be divided by 2 before being sent out over the network. Even though G722 is 16 kHz, an error in some previous spec has made it so that we have to list the number of samples such as if it was 8 kHz. main/file.c: - When scheduling the next time to expect a frame, take into account that the format of the file we're reading from may not be 8 kHz. codecs/codec_g722.c: - When converting from G722 to slinear, g722_decode() expects its samples parameter to be in the silly (real samples / 2) format. Make it so. - When converting from slinear to G722, properly set the number of samples in the frame to be the number of bytes of output * 2. formats/format_pcm.c: - This format module handles G722, among a number of other formats. However, the read() and seek() functions did not account for the fact that G722 has 2 samples per byte. (closes issue #12130, reported by rickross, patched by me) ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@106502 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--codecs/codec_g722.c8
-rw-r--r--formats/format_pcm.c27
-rw-r--r--main/file.c6
-rw-r--r--main/rtp.c8
4 files changed, 36 insertions, 13 deletions
diff --git a/codecs/codec_g722.c b/codecs/codec_g722.c
index 99c3856bc..7dd2744c3 100644
--- a/codecs/codec_g722.c
+++ b/codecs/codec_g722.c
@@ -102,9 +102,13 @@ static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
{
struct g722_decoder_pvt *tmp = pvt->pvt;
int out_samples;
+ int in_samples;
+
+ /* g722_decode expects the samples to be in the invalid samples / 2 format */
+ in_samples = f->samples / 2;
out_samples = g722_decode(&tmp->g722, (int16_t *) &pvt->outbuf[pvt->samples * sizeof(int16_t)],
- (uint8_t *) f->data, f->samples);
+ (uint8_t *) f->data, in_samples);
pvt->samples += out_samples;
@@ -121,7 +125,7 @@ static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
outlen = g722_encode(&tmp->g722, (uint8_t *) (&pvt->outbuf[pvt->datalen]),
(int16_t *) f->data, f->samples);
- pvt->samples += outlen;
+ pvt->samples += outlen * 2;
pvt->datalen += outlen;
diff --git a/formats/format_pcm.c b/formats/format_pcm.c
index c514b5863..118353552 100644
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -89,7 +89,10 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
return NULL;
}
s->fr.datalen = res;
- *whennext = s->fr.samples = res;
+ if (s->fmt->format == AST_FORMAT_G722)
+ *whennext = s->fr.samples = res * 2;
+ else
+ *whennext = s->fr.samples = res;
return &s->fr;
}
@@ -367,24 +370,32 @@ 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)
{
off_t min, max, cur;
- long offset = 0, samples;
-
- samples = sample_offset;
+ long offset = 0, bytes;
+
+ if (fs->fmt->format == AST_FORMAT_G722)
+ bytes = sample_offset / 2;
+ else
+ bytes = sample_offset;
+
min = AU_HEADER_SIZE;
cur = ftello(fs->f);
fseek(fs->f, 0, SEEK_END);
max = ftello(fs->f);
+
if (whence == SEEK_SET)
- offset = samples + min;
+ offset = bytes + min;
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = samples + cur;
+ offset = bytes + cur;
else if (whence == SEEK_END)
- offset = max - samples;
- if (whence != SEEK_FORCECUR) {
+ offset = max - bytes;
+
+ if (whence != SEEK_FORCECUR) {
offset = (offset > max) ? max : offset;
}
+
/* always protect the header space. */
offset = (offset < min) ? min : offset;
+
return fseeko(fs->f, offset, SEEK_SET);
}
diff --git a/main/file.c b/main/file.c
index fb684755e..1bec4fca4 100644
--- a/main/file.c
+++ b/main/file.c
@@ -669,7 +669,8 @@ static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
ast_settimeout(s->owner, whennext, ast_fsread_audio, s);
else
#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;
return FSREAD_SUCCESS_NOSCHED;
}
@@ -713,7 +714,8 @@ static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
}
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);
s->lasttimeout = whennext;
return FSREAD_SUCCESS_NOSCHED;
diff --git a/main/rtp.c b/main/rtp.c
index 433fa2c79..c449b8b17 100644
--- a/main/rtp.c
+++ b/main/rtp.c
@@ -3186,8 +3186,14 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_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);
+ }
} else {
/* Don't buffer outgoing frames; send them one-per-packet: */
if (_f->offset < hdrlen)