]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
I thought I was going to be able to leave 1.4 alone, but that was not the case.
authorRussell Bryant <russell@russellbryant.com>
Tue, 22 Apr 2008 21:14:55 +0000 (21:14 +0000)
committerRussell Bryant <russell@russellbryant.com>
Tue, 22 Apr 2008 21:14:55 +0000 (21:14 +0000)
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

formats/format_pcm.c
main/channel.c
main/file.c
main/rtp.c

index 6facfcdcc41f41e1880c8b9c758ced94a45b8c06..7b186e6021278bf25a20756d2e8451383c4bafab 100644 (file)
@@ -102,7 +102,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;
 }
 
@@ -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)
 {
        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;
+               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);
 }
 
index 91dd940c7cc0c1c6ac5376b45d260fffbcd9f1bb..f61d365b70a9d099f621ddce8080582db8f769a1 100644 (file)
@@ -1573,7 +1573,7 @@ static int generator_force(const void *data)
        if (!tmp || !generate)
                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;
 
@@ -1889,6 +1889,7 @@ static void ast_read_generator_actions(struct ast_channel *chan, struct ast_fram
                void *tmp = chan->generatordata;
                int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
                int res;
+               int samples;
 
                if (chan->timingfunc) {
                        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 */
+
+               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) {
                        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
                 */
                ast_channel_unlock(chan);
-               res = generate(chan, tmp, f->datalen, f->samples);
+               res = generate(chan, tmp, f->datalen, samples);
                ast_channel_lock(chan);
                chan->generatordata = tmp;
                if (res) {
index c44941b2baf2a330727ec2787154016b4422e000..340eb4ee396021ec3e22d50f117fc7d67f354582 100644 (file)
@@ -680,11 +680,21 @@ static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
        }
        if (whennext != s->lasttimeout) {
 #ifdef HAVE_ZAPTEL
-               if (s->owner->timingfd > -1)
-                       ast_settimeout(s->owner, whennext, ast_fsread_audio, s);
-               else
+               if (s->owner->timingfd > -1) {
+                       int zap_timer_samples = whennext;
+                       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         
-                       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;
        }
@@ -728,7 +738,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;
index 3621d3610a34d96cdc6ac1293a3427baa6fe6b45..658bd08910a47003dbb6fe1e9b41fd630ccdb5d6 100644 (file)
@@ -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 */
                ast_set_flag(&rtp->f, AST_FRFLAG_HAS_TIMING_INFO);
                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 {
                /* Video -- samples is # of samples vs. 90000 */
                if (!rtp->lastividtimestamp)
@@ -2795,17 +2795,28 @@ 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: */
+               /* Don't buffer outgoing frames; send them one-per-packet: */
                if (_f->offset < hdrlen) {
                        f = ast_frdup(_f);
                } else {
                        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);
+               }
                if (f != _f)
                        ast_frfree(f);
        }