root/rat/trunk/source.c @ 3006

Revision 3006, 59.9 KB (checked in by ucacoxh, 15 years ago)

- removed SunOS specifics from config_unix.h.
- removed old Linux and SGI specifics. All catered for by configure tests.
- pushed audio_types.h include out of config_{unix,win32}.h.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * FILE:      source.c
3 * AUTHOR(S): Orion Hodson
4 *
5 * Layering support added by Tristan Henderson.
6 *     
7 * $Revision$
8 * $Date$
9 *
10 * Copyright (c) 1999 University College London
11 * All rights reserved.
12 *
13 */
14
15#include "config_unix.h"
16#include "config_win32.h"
17#include "audio_types.h"
18#include "codec_types.h"
19#include "ts.h"
20#include "playout.h"
21#include "channel.h"
22#include "channel_types.h"
23#include "codec.h"
24#include "codec_state.h"
25#include "converter.h"
26#include "audio_util.h"
27#include "render_3D.h"
28#include "repair.h"
29#include "timers.h"
30#include "ts.h"
31#include "channel_types.h"
32#include "pdb.h"
33#include "pktbuf.h"
34#include "source.h"
35#include "debug.h"
36#include "util.h"
37#include "net_udp.h"
38#include "mix.h"
39#include "rtp.h"
40#include "playout_calc.h"
41#include "ui.h"
42#include "session.h"
43#include "auddev.h"
44
45#define SKEW_ADAPT_THRESHOLD       5000
46#define SOURCE_YOUNG_AGE             20
47#define SOURCE_AUDIO_HISTORY_MS    1000
48#define NO_TOGED_CONT_FOR_PLAYOUT_RECALC 3
49
50#define SOURCE_COMPARE_WINDOW_SIZE 8
51/* Match threshold is mean abs diff. lower score gives less noise, but less  */
52/* adaption..., might be better if threshold adapted with how much extra     */
53/* data we have buffered...                                                  */
54#define MATCH_THRESHOLD 1200
55
56/* constants for skew adjustment:
57 SOURCE_SKEW_SLOW - denotes source clock appears slower than ours.
58 SOURCE_SKEW_FAST - denotes source clock appears faster than ours.
59*/
60typedef enum { SOURCE_SKEW_SLOW, SOURCE_SKEW_FAST, SOURCE_SKEW_NONE } skew_t;
61
62typedef enum { PLAYOUT_MODE_NORMAL, PLAYOUT_MODE_SPIKE } pmode_t;
63
64typedef struct s_source {
65        struct s_source            *next;
66        struct s_source            *prev;
67        pdb_entry_t                *pdbe;       /* persistent database entry */
68        uint32_t                    age;
69        ts_t                        next_played; /* anticipated next unit    */
70        ts_t                        last_repair;
71        ts_t                        talkstart;  /* start of latest talkspurt */
72        uint32_t                    post_talkstart_units;
73        uint16_t                    consec_lost;
74        uint32_t                    mean_energy;
75        struct s_pktbuf            *pktbuf;
76        uint32_t                    packets_done;
77        struct s_channel_state     *channel_state;
78        struct s_codec_state_store *codec_states;
79        struct s_pb                *channel;
80        struct s_pb                *media;
81        struct s_pb_iterator       *media_pos;
82        struct s_converter         *converter;
83        pmode_t                     playout_mode; /* SPIKE, NORMAL */
84        ts_t                        spike_var;
85        /* Fine grained playout buffer adjustment variables.  Used in        */
86        /* attempts to correct for clock skew between source and local host. */
87        skew_t                      skew;
88        ts_t                        skew_adjust;
89        int16_t                     skew_cnt;
90        /* Skew stats                                                        */
91        int32_t                     samples_played;
92        int32_t                     samples_added;
93        /* b/w estimation variables                                          */
94        uint32_t                    byte_count;
95        ts_t                        byte_count_start;
96        double                      bps;
97        /* Playout stats (most in pdb_entry_t)                               */
98        u_char                      toged_cont;      /* Toged in a row       */
99        uint16_t                    toged_mask;      /* bitmap hist. of tog  */
100} source;
101
102/* A linked list is used for sources and this is fine since we mostly expect */
103/* 1 or 2 sources to be simultaneously active and so efficiency is not a     */
104/* killer.                                                                   */
105
106typedef struct s_source_list {
107        source  sentinel;
108        uint16_t nsrcs;
109} source_list;
110
111/*****************************************************************************/
112/* Source List functions.  Source List is used as a container for sources    */
113/*****************************************************************************/
114
115int
116source_list_create(source_list **pplist)
117{
118        source_list *plist = (source_list*)xmalloc(sizeof(source_list));
119        if (plist != NULL) {
120                *pplist = plist;
121                plist->sentinel.next = &plist->sentinel;
122                plist->sentinel.prev = &plist->sentinel;
123                plist->nsrcs = 0;
124                return TRUE;
125        }
126        return FALSE;
127}
128
129void
130source_list_clear(source_list *plist)
131{
132       assert(plist != NULL);
133       
134       while(plist->sentinel.next != &plist->sentinel) {
135               source_remove(plist, plist->sentinel.next);
136       }
137}
138
139void
140source_list_destroy(source_list **pplist)
141{
142        source_list *plist = *pplist;
143        source_list_clear(plist);
144        assert(plist->nsrcs == 0);
145        xfree(plist);
146        *pplist = NULL;
147}
148
149uint32_t
150source_list_source_count(source_list *plist)
151{
152        return plist->nsrcs;
153}
154
155source*
156source_list_get_source_no(source_list *plist, uint32_t n)
157{
158        source *curr = NULL;
159
160        assert(plist != NULL);
161
162        if (n < plist->nsrcs) {
163                curr = plist->sentinel.next;
164                while(n != 0) {
165                        curr = curr->next;
166                        n--;
167                }
168                return curr;
169        }
170        return NULL;
171}
172
173source*
174source_get_by_ssrc(source_list *plist, uint32_t ssrc)
175{
176        source *curr = NULL, *stop = NULL;
177       
178        curr = plist->sentinel.next;
179        stop = &plist->sentinel;
180        while(curr != stop) {
181                if (curr->pdbe->ssrc == ssrc) {
182                        return curr;
183                }
184                curr = curr->next;
185        }
186 
187        return NULL;
188}
189
190/*****************************************************************************/
191/* Timestamp constants and initialization                                    */
192/*****************************************************************************/
193
194static ts_t zero_ts;        /* No time at all :-)                            */
195static ts_t keep_source_ts; /* How long source kept after source goes quiet  */
196static ts_t history_ts;     /* How much old audio hang onto for repair usage */
197static ts_t bw_avg_period;  /* Average period for bandwidth estimate         */
198static ts_t skew_thresh;    /* Significant size b4 consider playout adapt    */
199static ts_t skew_limit;     /* Upper bound, otherwise clock reset.           */
200static ts_t transit_reset;  /* Period after which new transit time taken     */
201                            /* if source has been quiet.                     */
202static ts_t spike_jump;     /* Packet spike delay threshold (trigger).       */
203static ts_t spike_end;      /* Value of var when spike over                  */
204static int  time_constants_inited = FALSE;
205
206static void
207time_constants_init()
208{
209        /* We use these time constants *all* the time.   Initialize once     */
210        zero_ts        = ts_map32(8000, 0);
211        keep_source_ts = ts_map32(8000, 24000);
212        history_ts     = ts_map32(8000, 1000);
213        bw_avg_period  = ts_map32(8000, 8000);
214        skew_thresh    = ts_map32(8000, 320);
215        skew_limit     = ts_map32(8000, 4000);
216        transit_reset  = ts_map32(8000, 80000);
217        spike_jump     = ts_map32(8000, 800);
218        spike_end      = ts_map32(8000, 64);
219        time_constants_inited = TRUE;
220}
221
222/*****************************************************************************/
223/* Source functions.  A source is an active audio source.                    */
224/*****************************************************************************/
225
226source*
227source_create(source_list    *plist,
228              uint32_t         ssrc,
229              pdb_t          *pdb)
230{
231        source *psrc;
232        int     success;
233
234        assert(plist != NULL);
235        assert(source_get_by_ssrc(plist, ssrc) == NULL);
236
237        /* Time constant initialization. Nothing to do with source creation  */
238        /* just has to go somewhere before sources might be active, here it  */
239        /* definitely is!                                                    */
240        if (time_constants_inited == FALSE) {
241                time_constants_init();
242        }
243
244        /* On with the show...                                               */
245        psrc = (source*)block_alloc(sizeof(source));
246        if (psrc == NULL) {
247                return NULL;
248        }
249        memset(psrc, 0, sizeof(source));
250
251        if (pdb_item_get(pdb, ssrc, &psrc->pdbe) == FALSE) {
252                debug_msg("Persistent database item not found\n");
253                abort();
254        }
255
256        psrc->pdbe->first_mix  = 1; /* Used to note nothing mixed anything   */
257        psrc->toged_cont       = 0; /* Reset continuous thrown on ground cnt */
258        psrc->toged_mask       = 0;
259        psrc->channel_state    = NULL;       
260        psrc->skew             = SOURCE_SKEW_NONE;
261        psrc->samples_played   = 0;
262        psrc->samples_added    = 0;
263        psrc->spike_var        = zero_ts;
264
265        /* Allocate channel and media buffers                                */
266        success = pb_create(&psrc->channel,
267                            (playoutfreeproc)channel_data_destroy);
268        if (!success) {
269                debug_msg("Failed to allocate channel buffer\n");
270                goto fail_create_channel;
271        }
272
273        success = pb_create(&psrc->media, (playoutfreeproc)media_data_destroy);
274        if (!success) {
275                debug_msg("Failed to allocate media buffer\n");
276                goto fail_create_media;
277        }
278
279        success = pb_iterator_create(psrc->media, &psrc->media_pos);
280        if (!success) {
281                debug_msg("Failed to attach iterator to media buffer\n");
282                goto fail_create_iterator;
283        }
284
285        success = codec_state_store_create(&psrc->codec_states, DECODER);
286        if (!success) {
287                debug_msg("Failed to allocate codec state storage\n");
288                goto fail_create_states;
289        }
290
291        success = pktbuf_create(&psrc->pktbuf, 32);
292        if (!success) {
293                debug_msg("Failed to allocate packet buffer\n");
294                goto fail_pktbuf;
295        }
296
297        /* List maintenance    */
298        psrc->next = plist->sentinel.next;
299        psrc->prev = &plist->sentinel;
300        psrc->next->prev = psrc;
301        psrc->prev->next = psrc;
302        plist->nsrcs++;
303
304        debug_msg("Created source decode path\n");
305
306        return psrc;
307
308        /* Failure fall throughs */
309fail_pktbuf:
310        codec_state_store_destroy(&psrc->codec_states);
311fail_create_states:
312        pb_iterator_destroy(psrc->media, &psrc->media_pos);       
313fail_create_iterator:
314        pb_destroy(&psrc->media);
315fail_create_media:
316        pb_destroy(&psrc->channel);
317fail_create_channel:
318        block_free(psrc, sizeof(source));
319
320        return NULL;
321}
322
323/* All sources need to be reconfigured when anything changes in
324 * audio path.  These include change of device frequency, change of
325 * the number of channels, etc..
326 */
327
328void
329source_reconfigure(source        *src,
330                   converter_id_t conv_id,
331                   int            render_3d,
332                   uint16_t        out_rate,
333                   uint16_t        out_channels)
334{
335        uint16_t    src_rate, src_channels;
336        codec_id_t            src_cid;
337        const codec_format_t *src_cf;
338
339        assert(src->pdbe != NULL);
340
341        /* Set age to zero and flush existing media
342         * so that repair mechanism does not attempt
343         * to patch across different block sizes.
344         */
345
346        src->age = 0;
347        pb_flush(src->media);
348
349        /* Get rate and channels of incoming media so we know
350         * what we have to change.
351         */
352        src_cid = codec_get_by_payload(src->pdbe->enc);
353        src_cf  = codec_get_format(src_cid);
354        src_rate     = (uint16_t)src_cf->format.sample_rate;
355        src_channels = (uint16_t)src_cf->format.channels;
356
357        if (render_3d) {
358                assert(out_channels == 2);
359                /* Rejig 3d renderer if there, else create */
360                if (src->pdbe->render_3D_data) {
361                        int azi3d, fil3d, len3d;
362                        render_3D_get_parameters(src->pdbe->render_3D_data,
363                                                 &azi3d,
364                                                 &fil3d,
365                                                 &len3d);
366                        render_3D_set_parameters(src->pdbe->render_3D_data,
367                                                 (int)src_rate,
368                                                 azi3d,
369                                                 fil3d,
370                                                 len3d);
371                } else {
372                        src->pdbe->render_3D_data = render_3D_init((int)src_rate);
373                }
374                assert(src->pdbe->render_3D_data);
375                /* Render 3d is before sample rate/channel conversion, and   */
376                /* output 2 channels.                                        */
377                src_channels = 2;
378        } else {
379                /* Rendering is switched off so destroy info.                */
380                if (src->pdbe->render_3D_data != NULL) {
381                        render_3D_free(&src->pdbe->render_3D_data);
382                }
383        }
384
385        /* Now destroy converter if it is already there.                     */
386        if (src->converter) {
387                converter_destroy(&src->converter);
388        }
389
390        if (src_rate != out_rate || src_channels != out_channels) {
391                converter_fmt_t c;
392                c.src_freq      = src_rate;
393                c.from_channels = src_channels;
394                c.dst_freq      = out_rate;
395                c.to_channels   = out_channels;
396                converter_create(conv_id, &c, &src->converter);
397        }
398        src->byte_count = 0;
399        src->bps        = 0.0;
400}
401
402void
403source_remove(source_list *plist, source *psrc)
404{
405        assert(plist);
406        assert(psrc);
407        assert(source_get_by_ssrc(plist, psrc->pdbe->ssrc) != NULL);
408
409        psrc->next->prev = psrc->prev;
410        psrc->prev->next = psrc->next;
411
412        if (psrc->channel_state) {
413                channel_decoder_destroy(&psrc->channel_state);
414        }
415
416        if (psrc->converter) {
417                converter_destroy(&psrc->converter);
418        }
419
420        pb_iterator_destroy(psrc->media, &psrc->media_pos);
421        pb_destroy(&psrc->channel);
422        pb_destroy(&psrc->media);
423        codec_state_store_destroy(&psrc->codec_states);
424        pktbuf_destroy(&psrc->pktbuf);
425        plist->nsrcs--;
426
427        debug_msg("Destroying source decode path\n");
428       
429        block_free(psrc, sizeof(source));
430
431        assert(source_get_by_ssrc(plist, psrc->pdbe->ssrc) == NULL);
432}
433             
434/* Source Processing Routines ************************************************/
435
436/* Returns true if fn takes ownership responsibility for data */
437static int
438source_process_packet (source  *src,
439                       u_char  *pckt,
440                       uint32_t pckt_len,
441                       uint8_t  payload,
442                       ts_t     playout)
443{
444        channel_data *cd;
445        channel_unit *cu;
446        cc_id_t       cid;
447        uint8_t        clayers;
448
449        assert(src != NULL);
450        assert(pckt != NULL);
451
452        /* Need to check:
453         * (i) if layering is enabled
454         * (ii) if channel_data exists for this playout point (if pb_iterator_get_at...)
455         * Then need to:
456         * (i) create cd if doesn't exist
457         * (ii) add packet to cd->elem[layer]
458         * We work out layer number by deducting the base port
459         * no from the port no this packet came from
460         * But what if layering on one port?
461         */
462
463        /* Or we could:
464         * (i) check if cd exists for this playout point
465         * (ii) if so, memcmp() to see if this packet already exists (ugh!)
466         */
467
468        cid = channel_coder_get_by_payload(payload);
469        clayers = channel_coder_get_layers(cid);
470        if (clayers > 1) {
471                struct s_pb_iterator *pi;
472                uint8_t i;
473                uint32_t clen;
474                int dup;
475                ts_t lplayout;
476                pb_iterator_create(src->channel, &pi);
477                while(pb_iterator_advance(pi)) {
478                        pb_iterator_get_at(pi, (u_char**)&cd, &clen, &lplayout);
479                       /* if lplayout==playout there is already channel_data for this playout point */
480                        if(!ts_eq(playout, lplayout)) {
481                                continue;
482                        }
483                        pb_iterator_detach_at(pi, (u_char**)&cd, &clen, &lplayout);
484                        assert(cd->nelem >= 1);
485
486                       /* if this channel_data is full, this new packet must *
487                        * be a duplicate, so we don't need to check          */
488                        if(cd->nelem >= clayers) {
489                                debug_msg("source_process_packet failed - duplicate layer\n");
490                                src->pdbe->duplicates++;
491                                pb_iterator_destroy(src->channel, &pi);
492                                goto done;
493                        }
494
495                        cu = (channel_unit*)block_alloc(sizeof(channel_unit));
496                        cu->data     = pckt;
497                        cu->data_len = pckt_len;
498                        cu->pt       = payload;
499
500                        dup = 0;
501
502                       /* compare existing channel_units to this one */
503                        for(i=0; i<cd->nelem; i++) {
504                                if(cu->data_len!=cd->elem[i]->data_len) break;
505                                /* This memcmp arbitrarily only checks
506                                 * 20 bytes, otherwise it takes too
507                                 * long */
508                                if (memcmp(cu->data, cd->elem[i]->data, 20) == 0) {
509                                        dup=1;
510                                }
511                        }
512
513                       /* duplicate, so stick the channel_data back on *
514                        * the playout buffer and swiftly depart        */
515                        if(dup) {
516                                debug_msg("source_process_packet failed - duplicate layer\n");
517                                src->pdbe->duplicates++;
518                                /* destroy temporary channel_unit */
519                                block_free(cu->data, cu->data_len);
520                                cu->data_len = 0;
521                                block_free(cu, sizeof(channel_unit));
522                                pb_iterator_destroy(src->channel, &pi);
523                                goto done;
524                        }
525
526                       /* add this layer if not a duplicate           *
527                        * NB: layers are not added in order, and thus *
528                        * have to be reorganised in the layered       *
529                        * channel coder                               */
530                        cd->elem[cd->nelem] = cu;
531                        cd->nelem++;
532                        pb_iterator_destroy(src->channel, &pi);
533                        goto done;
534                }
535                pb_iterator_destroy(src->channel, &pi);
536        }
537
538        if (channel_data_create(&cd, 1) == 0) {
539                return FALSE;
540        }
541       
542        cu               = cd->elem[0];
543        cu->data         = pckt;
544        cu->data_len     = pckt_len;
545        cu->pt           = payload;
546
547        src->age++;
548done:   
549        if (pb_add(src->channel, (u_char*)cd, sizeof(channel_data), playout) == FALSE) {
550                src->pdbe->duplicates++;
551                channel_data_destroy(&cd, sizeof(channel_data));
552        }
553
554        return TRUE;
555}
556
557#ifdef SOURCE_LOG_PLAYOUT
558
559static FILE *psf; /* Playout stats file */
560static uint32_t t0;
561
562static void
563source_close_log(void)
564{
565        if (psf) {
566                fclose(psf);
567                psf = NULL;
568        }
569}
570
571static void
572source_playout_log(source *src, uint32_t ts, ts_t now)
573{
574        if (psf == NULL) {
575                psf = fopen("playout.log", "w");
576                if (psf == NULL) {
577                        fprintf(stderr, "Could not open playout.log\n");
578                } else {
579                        atexit(source_close_log);
580                        fprintf(psf, "# <RTP timestamp> <talkstart> <jitter> <transit> <avg transit> <last transit> <playout del> <spike_var> <arr time>\n");
581                }
582                t0 = ts - 1000; /* -1000 in case of out of order first packet */
583        }
584
585        fprintf(psf, "%.6f %5u %5u %5u %5u %5u %5u %5u %5u\n",
586                (ts - t0)/8000.0,
587                ts_to_ms(src->talkstart),
588                ts_to_ms(src->pdbe->jitter),
589                ts_to_ms(src->pdbe->transit),
590                ts_to_ms(src->pdbe->avg_transit),
591                ts_to_ms(src->pdbe->last_transit),
592                ts_to_ms(src->pdbe->playout),
593                ts_to_ms(src->spike_var),
594                ts_to_ms(now)
595                );
596}
597
598#endif /* SOURCE_LOG_PLAYOUT */
599
600static void
601source_update_toged(source *src, int toged)
602{
603        src->toged_mask <<= 1;
604        src->toged_mask |= toged;
605        src->toged_cont = 0;
606        if (toged == 1) {
607                int m;
608                m = src->toged_mask & 0xff; /* Last 8 packets */
609                while (m) {
610                        src->toged_cont += (m & 1);
611                        m >>= 1;
612                }
613        }
614}
615
616static void
617source_process_packets(session_t *sp, source *src, ts_t now)
618{
619
620        ts_t    src_ts, playout, transit;
621        pdb_entry_t    *e;
622        rtp_packet     *p;
623        cc_id_t         ccid = -1;
624        uint16_t        units_per_packet = -1;
625        uint32_t        delta_ts, delta_seq;
626        uint8_t         codec_pt;
627        uint8_t         adjust_playout;
628
629        e = src->pdbe;
630        while(pktbuf_dequeue(src->pktbuf, &p)) {
631                adjust_playout = FALSE;
632               
633                ccid = channel_coder_get_by_payload((u_char)p->pt);
634                if (channel_verify_and_stat(ccid, (u_char)p->pt,
635                                            p->data, p->data_len,
636                                            &units_per_packet, &codec_pt) == FALSE) {
637                        debug_msg("Packet discarded: packet failed channel verify.\n");
638                        xfree(p);
639                        continue;
640                }
641
642                if (e->channel_coder_id != ccid ||
643                    e->enc              != codec_pt ||
644                    e->units_per_packet != units_per_packet ||
645                    src->packets_done == 0) {
646                        /* Something has changed or is uninitialized...      */
647                        const codec_format_t *cf;
648                        const audio_format   *dev_fmt;
649                        codec_id_t            cid;
650                        uint32_t              samples_per_frame;
651
652                        cid = codec_get_by_payload(codec_pt);
653                        cf  = codec_get_format(cid);
654                        /* Fix clock.                                        */
655                        change_freq(e->clock, cf->format.sample_rate);
656                        /* Fix details.                                      */
657                        e->enc              = codec_pt;
658                        e->units_per_packet = units_per_packet;
659                        e->channel_coder_id = ccid;       
660                        if (src->channel_state != NULL) {
661                                channel_decoder_destroy(&(src->channel_state));
662                                pb_flush(src->channel);
663                        }
664                        channel_decoder_create(e->channel_coder_id, &(src->channel_state));
665                        samples_per_frame   = codec_get_samples_per_frame(cid);
666                        debug_msg("Samples per frame %d rate %d\n", samples_per_frame, cf->format.sample_rate);
667                        e->inter_pkt_gap    = e->units_per_packet * (uint16_t)samples_per_frame;
668                        e->frame_dur        = ts_map32(cf->format.sample_rate, samples_per_frame);
669                        /* Get string describing encoding.                   */
670                        channel_describe_data(ccid, codec_pt,
671                                              p->data, p->data_len,
672                                              e->enc_fmt, e->enc_fmt_len);
673                        if (sp->mbus_engine) {
674                                ui_update_stats(sp, e->ssrc);
675                        }
676                        debug_msg("Encoding changed to %s\n", e->enc_fmt);
677                        /* Configure converter */
678                        dev_fmt = audio_get_ofmt(sp->audio_device);
679                        source_reconfigure(src,
680                                           sp->converter,
681                                           sp->render_3d,
682                                           (uint16_t)dev_fmt->sample_rate,
683                                           (uint16_t)dev_fmt->channels);
684                        adjust_playout = TRUE;
685                }
686               
687                /* Check for talkspurt start: indicated either by the marker bit,  */
688                /* or by a change in the relationship between timestamps and       */
689                /* sequence numbers.                                               */
690                delta_seq = p->seq - e->last_seq;
691                delta_ts  = p->ts  - e->last_ts;
692                if (delta_seq * e->inter_pkt_gap != delta_ts) {
693                        debug_msg("Seq no / timestamp realign (%lu * %lu != %lu)\n", delta_seq, e->inter_pkt_gap, delta_ts);
694                        adjust_playout = TRUE;
695                }
696                if (p->m) {
697                        adjust_playout = TRUE;
698                        debug_msg("New Talkspurt: %lu\n", p->ts);
699                }
700
701                src_ts = ts_seq32_in(&e->seq, get_freq(e->clock), p->ts);
702                transit = ts_sub(now, src_ts);
703
704                /* Spike adaptation - Ramjee, Kurose, Towsley, and Schulzerinne.   */
705                /* Adaptive Playout Mechanisms for Packetized Audio Applications   */
706                /* in Wide-Area Networks, IEEE Infocom 1994, pp 680-688.           */
707                if (adjust_playout == FALSE) {
708                        ts_t spt, delta_transit;
709                        spt           = ts_mul(e->playout, 2);  /* Spike threshold */
710                        spt           = ts_add(spt, spike_jump);
711                        delta_transit = ts_sub(transit, e->last_transit);
712                        if (ts_gt(delta_transit, spt)) {
713                                /* Transit delay increased suddenly - this is a "spike" */
714                                debug_msg("Spike\n");
715                                src->playout_mode = PLAYOUT_MODE_SPIKE;
716                                src->spike_var    = zero_ts;
717                                e->spike_events++;
718                        } else {
719                                if (src->playout_mode == PLAYOUT_MODE_SPIKE) {
720                                        ts_t delta_var;
721                                        src->spike_var = ts_div(src->spike_var, 2);
722                                        delta_var = ts_add(ts_abs_diff(transit, e->last_transit),
723                                                           ts_abs_diff(transit, e->last_last_transit));
724                                        delta_var = ts_div(delta_var, 8);
725                                        src->spike_var = ts_add(src->spike_var, delta_var);
726                                        if (ts_gt(spike_end, src->spike_var)) {
727                                                debug_msg("Normal mode.\n");
728                                                src->playout_mode = PLAYOUT_MODE_NORMAL;
729                                        }
730                                }
731                        }
732                } else {
733                        src->playout_mode = PLAYOUT_MODE_NORMAL;
734                }
735
736                /* Check for continuous number of packets being discarded.   */
737                /* This happens when jitter or transit estimate is no longer */
738                /* consistent with the real world.                           */
739                if (src->toged_cont >= NO_TOGED_CONT_FOR_PLAYOUT_RECALC) {
740                        adjust_playout  = TRUE;
741                        src->toged_cont = 0;
742                        debug_msg("Cont_toged\n");
743                        /* We've been dropping packets so take a new transit */
744                        /* estimate.  Last one has expired.                  */
745                        e->avg_transit = transit;
746                }
747               
748                if (adjust_playout && (ts_gt(ts_sub(now, e->last_arr), transit_reset) || (e->received < 20))) {
749                        /* Source has been quiet for a long time.  Discard   */
750                        /* old average transit estimate.                     */
751                        e->avg_transit = transit;
752                }
753
754                /* Calculate the playout point for this packet.              */
755                /* Playout calc updates avg_transit and jitter.              */
756                /* Do not call if in spike mode as it distorts both.         */
757                if (src->playout_mode == PLAYOUT_MODE_NORMAL) {
758                        playout = playout_calc(sp, e->ssrc, transit, adjust_playout);
759                } else {
760                        playout = e->playout;
761                }
762
763                if ((p->m || src->packets_done == 0) && ts_gt(playout, e->frame_dur)) {
764                        /* Packets are likely to be compressed at talkspurt  */
765                        /* start because of VAD going back and grabbing      */
766                        /* frames.                                           */
767                        playout = ts_sub(playout, e->frame_dur);
768                        debug_msg("New ts shift XXX\n");
769                }
770
771                playout = ts_add(e->transit, playout);
772                playout = ts_add(src_ts, playout);
773
774                if (adjust_playout) {
775                        if (ts_valid(src->next_played) && ts_gt(src->next_played, playout)) {
776                                /* Talkspurts would have overlapped.  May     */
777                                /* cause problems for redundancy decoder.     */
778                                /* Don't take any chances.                    */
779                                ts_t overlap = ts_sub(src->next_played, playout);
780                                debug_msg("Overlap %d us\n", ts_to_us(overlap));
781                                e->playout   = ts_add(e->playout, overlap);
782                                playout      = ts_add(playout, overlap);
783                        }
784                        src->talkstart = playout; /* Note start of new talkspurt  */
785                        src->post_talkstart_units = 0;
786                } else {
787                        src->post_talkstart_units++;
788                }
789
790                if (src->packets_done == 0) {
791                        /* This is first packet so expect next played to have its */
792                        /* playout.                                               */
793                        src->next_played = playout;
794                }
795
796                if (!ts_gt(now, playout)) {
797                        u_char  *u;
798                        u    = (u_char*)block_alloc(p->data_len);
799                        /* Would be great if memcpy occured after validation */
800                        /* in source_process_packet (or not at all)          */
801                        memcpy(u, p->data, p->data_len);
802                        if (source_process_packet(src, u, p->data_len, codec_pt, playout) == FALSE) {
803                                block_free(u, (int)p->data_len);
804                        }
805                        source_update_toged(src, 0);
806                } else {
807                        /* Packet being decoded is before start of current  */
808                        /* so there is now way it's audio will be played    */
809                        /* Playout recalculation gets triggered in          */
810                        /* rtp_callback if toged_cont hits a critical       */
811                        /* threshold.  It signifies current playout delay   */
812                        /* is inappropriate.                                */
813                        if (src->playout_mode == PLAYOUT_MODE_NORMAL) {
814                                debug_msg("Packet late (compared to now)\n");
815                                source_update_toged(src, 1);
816                                src->pdbe->jit_toged++;
817                        } else {
818                                /* Spike mode - don't worry about jit_toged */
819                                src->pdbe->spike_toged++;
820                        }
821                }
822
823                /* Update persistent database fields.                        */
824                if (e->last_seq > p->seq) {
825                        e->misordered++;
826                }
827                e->last_seq     = p->seq;
828                e->last_ts      = p->ts;
829                e->last_arr     = now;
830                e->last_last_transit = e->last_transit;
831                e->last_transit      = transit;
832                /* This would be a good place to log a histogram of loss     */
833                /* lengths, right? llhist[p->seq - e->last_seq]++ after a    */
834                /* check that this is not the first packet in a talkspurt.   */
835                /* We could then feed it back to the sender in our reception */
836                /* reports, where it could be used to adapt the redundancy   */
837                /* offset, for example. [csp]                                */
838
839#ifdef SOURCE_LOG_PLAYOUT
840                source_playout_log(src, p->ts, now);
841#endif /* SOURCE_LOG_PLAYOUT */
842                src->packets_done++;
843                xfree(p);
844        }
845}
846
847int
848source_add_packet (source     *src,
849                   rtp_packet *pckt)
850{
851        src->byte_count += pckt->data_len;
852        return pktbuf_enqueue(src->pktbuf, pckt);
853}
854
855static void
856source_update_bps(source *src, ts_t now)
857{
858        ts_t delta;
859        if (!ts_valid(src->byte_count_start)) {
860                src->byte_count_start = now;
861                src->byte_count       = 0;
862                src->bps              = 0.0;
863                return;
864        }
865
866        delta = ts_sub(now, src->byte_count_start);
867       
868        if (ts_gt(delta, bw_avg_period)) {
869                double this_est;
870                this_est = 8.0 * src->byte_count * 1000.0/ ts_to_ms(delta);
871                if (src->bps == 0.0) {
872                        src->bps = this_est;
873                } else {
874                        src->bps += (this_est - src->bps)/2.0;
875                }
876                src->byte_count = 0;
877                src->byte_count_start = now;
878        }
879}
880
881double 
882source_get_bps(source *src)
883{
884        return src->bps;
885}
886
887static uint16_t
888find_local_match(sample *buffer, uint16_t wstart, uint16_t wlen, uint16_t sstart, uint16_t send, uint16_t channels)
889{
890        uint16_t i,j, i_min = sstart;
891        uint32_t score = 0, score_min = 0xffffffff;
892
893        for (i = sstart; i < send; i += channels) {
894                score = 0;
895                for(j = 0; j < wlen; j += channels) {
896                        score += abs(buffer[wstart + j] - buffer[i + j]);
897                }
898                if (score < score_min) {
899                        score_min = score;
900                        i_min     = i;
901                }
902        }
903
904        if (score_min / wlen < MATCH_THRESHOLD) {
905                return i_min;
906        }
907        return 0;
908}
909
910/* recommend_skew_adjust_dur examines a frame to determine how much audio    */
911/* to insert or drop.   Argument drop is boolean to indicate whether         */
912/* dropping samples (TRUE) or inserting (FALSE).                             */
913
914static ts_t
915recommend_skew_adjust_dur(media_data *md, int drop)
916{
917        uint16_t matchlen;
918        uint16_t rate, channels, samples;
919        sample *buffer;
920        int16_t i;
921
922        i = md->nrep - 1;
923        while(i >= 0) {
924                if (codec_get_native_info(md->rep[i]->id, &rate, &channels)) {
925                        break;
926                }
927                i--;
928        }
929        assert(i != -1);
930       
931        buffer  = (sample*)md->rep[i]->data;
932        samples = md->rep[i]->data_len / (sizeof(sample) * channels);
933        if (drop) {
934                /* match with first samples of frame */
935                /* start just past search window and finish at end of frame */
936                matchlen = find_local_match((sample*)md->rep[i]->data,
937                                            0,
938                                            SOURCE_COMPARE_WINDOW_SIZE * channels,
939                                            SOURCE_COMPARE_WINDOW_SIZE * channels,
940                                            (samples - SOURCE_COMPARE_WINDOW_SIZE) * channels,
941                                            channels);
942        } else {
943                /* match with last samples of frame.  Start at the start of   */
944                /* frame and finish just before search window.                */
945                matchlen = find_local_match((sample*)md->rep[i]->data,                             /* buffer */
946                                            (samples - SOURCE_COMPARE_WINDOW_SIZE) * channels,     /* wstart */
947                                            SOURCE_COMPARE_WINDOW_SIZE * channels,                 /* wlen   */
948                                            0,                                           /* sstart */
949                                            (samples - 2 * SOURCE_COMPARE_WINDOW_SIZE) * channels, /* slen   */
950                                            channels);
951                /* Want to measure from where frames will overlap.            */
952                matchlen = samples - matchlen - SOURCE_COMPARE_WINDOW_SIZE;
953        }
954
955        return ts_map32(rate, matchlen);
956}
957
958#define SOURCE_MERGE_LEN_SAMPLES 5
959
960static void
961conceal_dropped_samples(media_data *md, ts_t drop_dur)
962{
963        /* We are dropping drop_dur samples and want signal to be            */
964        /* continuous.  So we blend samples that would have been played if   */
965        /* they weren't dropped with where signal continues after the drop.  */
966        uint32_t drop_samples;
967        uint16_t rate, channels;
968        int32_t tmp, a, b, i, merge_len;
969        sample *new_start, *old_start;
970
971        for (i = md->nrep - 1; i >= 0; i--) {
972                if (codec_get_native_info(md->rep[i]->id, &rate, &channels)) {
973                        break;
974                }
975        }
976
977        assert(i != -1);
978
979        drop_dur     = ts_convert(rate, drop_dur);
980        drop_samples = channels * drop_dur.ticks;
981       
982        /* new_start is what will be played by mixer */
983        new_start = (sample*)md->rep[i]->data + drop_samples;
984        old_start = (sample*)md->rep[i]->data;
985
986        merge_len = SOURCE_MERGE_LEN_SAMPLES * channels;
987        for (i = 0; i < merge_len; i++) {
988                a   = (merge_len - i) * old_start[i];
989                b   = i * new_start[i];
990                tmp = (a + b) / merge_len;
991                new_start[i] = (sample)tmp;
992        }
993}
994
995/* Source conceal_inserted_samples blends end of omd with overlap in imd    */
996/* just before insert takes over.  Aims to provide transparent transitition */
997/* between added block and old block.                                       */
998
999static void
1000conceal_inserted_samples(media_data *omd, media_data *imd, ts_t insert_dur)
1001{
1002        uint16_t rate, channels;
1003        int32_t tmp, a, b, i, merge_len;
1004        sample *dst, *src;
1005
1006        assert(omd != NULL);
1007        assert(imd != NULL);
1008
1009        for (i = omd->nrep - 1; i >= 0; i--) {
1010                if (codec_get_native_info(omd->rep[i]->id, &rate, &channels)) {
1011                        break;
1012                }
1013        }
1014        assert(i >= 0);
1015        merge_len = SOURCE_MERGE_LEN_SAMPLES * channels;
1016        a         = omd->rep[i]->data_len / sizeof(sample) * channels - merge_len;
1017        dst       = (sample*)omd->rep[i]->data + a;
1018
1019        for (i = imd->nrep - 1; i >= 0; i--) {
1020                if (codec_get_native_info(imd->rep[i]->id, &rate, &channels)) {
1021                        break;
1022                }
1023        }
1024        assert(i >= 0);
1025        b   = insert_dur.ticks * channels;
1026        src = (sample*)imd->rep[i]->data + b;
1027
1028        for(i = 0; i < merge_len; i++) {
1029                a = (merge_len - i) * dst[i];
1030                b = i * src[i];
1031                tmp = (a + b) / merge_len;
1032                dst[i] = (sample)tmp;
1033        }
1034
1035        UNUSED(tmp);
1036}
1037
1038/* source_check_buffering is supposed to check amount of audio buffered      */
1039/* corresponds to what we expect from playout so we can think about skew     */
1040/* adjustment.                                                               */
1041
1042int
1043source_check_buffering(source *src)
1044{
1045        ts_t actual, desired, diff;
1046
1047        if (src->post_talkstart_units < 20) {
1048                /* If the source is new(ish) then not enough audio will be   */
1049                /* in the playout buffer because it hasn't arrived yet.      */
1050                return FALSE;
1051        }
1052
1053        actual  = source_get_audio_buffered(src);
1054        desired = source_get_playout_delay(src);
1055        diff    = ts_abs_diff(actual, desired);
1056
1057        if (ts_gt(actual, desired) && ts_gt(diff, skew_thresh)) {
1058                src->skew_adjust = diff;
1059                /* We're accumulating audio, their clock faster   */
1060                src->skew = SOURCE_SKEW_FAST;
1061                src->skew_cnt++;
1062                return TRUE;
1063        } else if (ts_gt(desired, actual)) {
1064                /* We're short of audio, so their clock is slower */
1065                /* Lower bound is much harder than upper bound    */
1066                /* since mixer will dry up / repair will start to */
1067                /* be invoked as we decode units late.            */
1068                src->skew_adjust = diff;
1069                src->skew = SOURCE_SKEW_SLOW;
1070                return TRUE;
1071        }
1072        src->skew = SOURCE_SKEW_NONE;
1073        src->skew_adjust = zero_ts;
1074        return FALSE;
1075}
1076
1077/* source_skew_adapt exists to shift playout units if source clock appears   */
1078/* to be fast or slow.  The media_data unit is here so that it can be        */
1079/* examined to see if it is low energy and adjustment would be okay.  Might  */
1080/* want to be more sophisticated and put a silence detector in rather than   */
1081/* static threshold.                                                         */
1082/*                                                                           */
1083/* Returns what adaption type occurred.                                      */
1084
1085static skew_t
1086source_skew_adapt(source *src, media_data *md, ts_t playout)
1087{
1088        uint32_t i = 0, e = 0, samples = 0;
1089        uint16_t rate, channels;
1090        ts_t adjustment, frame_dur;
1091
1092        assert(src);
1093        assert(md);
1094        assert(src->skew != SOURCE_SKEW_NONE);
1095
1096        for(i = 0; i < md->nrep; i++) {
1097                if (codec_get_native_info(md->rep[i]->id, &rate, &channels)) {
1098                        samples = md->rep[i]->data_len / (channels * sizeof(sample));
1099                        e = avg_audio_energy((sample*)md->rep[i]->data, samples * channels, channels);
1100                        src->mean_energy = (15 * src->mean_energy + e)/16;
1101                        frame_dur = ts_map32(rate, samples);
1102                        break;
1103                }
1104        }
1105
1106        if (i == md->nrep) {
1107                /* don't adapt if unit has not been decoded (error) or       */
1108                /* signal has too much energy                                */
1109                return SOURCE_SKEW_NONE;
1110        }
1111
1112        /* When we are making the adjustment we must shift playout buffers   */
1113        /* and timestamps that the source decode process uses.  Must be      */
1114        /* careful with last repair because it is not valid if no repair has */
1115        /* taken place.                                                      */
1116
1117        if (src->skew == SOURCE_SKEW_FAST && src->skew_cnt > 3) {
1118                /* source is fast so we need to bring units forward.
1119                 * Should only move forward at most a single unit
1120                 * otherwise we might discard something we have not
1121                 * classified.  */
1122
1123                if (ts_gt(skew_limit, src->skew_adjust)) {
1124                        adjustment = recommend_skew_adjust_dur(md, TRUE);
1125                } else {
1126                        /* Things are really skewed.  We're more than        */
1127                        /* skew_limit off of where we ought to be.  Just     */
1128                        /* drop a frame and don't worry.                     */
1129                        debug_msg("Dropping Frame\n");
1130                        adjustment = ts_div(src->pdbe->frame_dur, 2);
1131                }
1132
1133                if (ts_gt(adjustment, src->skew_adjust) || adjustment.ticks == 0) {
1134                        /* adjustment needed is greater than adjustment      */
1135                        /* period that best matches dropable by signal       */
1136                        /* matching.                                         */
1137                        return SOURCE_SKEW_NONE;
1138                }
1139                debug_msg("dropping %d / %d samples\n", adjustment.ticks, src->skew_adjust.ticks);
1140                pb_shift_forward(src->media,   adjustment);
1141                pb_shift_forward(src->channel, adjustment);
1142
1143                src->samples_added     += adjustment.ticks;
1144                src->pdbe->transit      = ts_sub(src->pdbe->transit, adjustment);
1145                src->skew_cnt           = 0;
1146                /* avg_transit and last_transit are fine.  Difference in     */
1147                /* avg_transit and transit triggered this adjustment.        */
1148
1149                if (ts_valid(src->last_repair)) {
1150                        src->last_repair = ts_sub(src->last_repair, adjustment);
1151                }
1152
1153                src->next_played = ts_sub(src->next_played, adjustment);
1154
1155                /* Remove skew adjustment from estimate of skew outstanding */
1156                if (ts_gt(src->skew_adjust, adjustment)) {
1157                        src->skew_adjust = ts_sub(src->skew_adjust, adjustment);
1158                } else {
1159                        src->skew = SOURCE_SKEW_NONE;
1160                }
1161
1162                conceal_dropped_samples(md, adjustment);
1163
1164                return SOURCE_SKEW_FAST;
1165        } else if (src->skew == SOURCE_SKEW_SLOW) {
1166                media_data *fmd;
1167                ts_t        insert_playout;
1168
1169                adjustment = recommend_skew_adjust_dur(md, FALSE);
1170                if (adjustment.ticks == 152) {
1171                        debug_msg("bad match\n");
1172                        return src->skew;
1173                }
1174                debug_msg("Insert %d samples\n", adjustment.ticks);
1175                pb_shift_units_back_after(src->media,   playout, adjustment);
1176                pb_shift_units_back_after(src->channel, playout, adjustment);
1177                src->pdbe->transit = ts_add(src->pdbe->transit, adjustment);
1178
1179                /* Insert a unit: buffer looks like current frame -> gap of adjustment -> next frame */
1180                media_data_dup(&fmd, md);
1181                insert_playout = ts_add(playout, adjustment);
1182
1183                if (pb_add(src->media, (u_char*)fmd, sizeof(media_data), insert_playout) == TRUE) {
1184                        conceal_inserted_samples(md, fmd, adjustment);
1185                } else {
1186                        debug_msg("Buffer push back: insert failed\n");
1187                        media_data_destroy(&fmd, sizeof(media_data));
1188                }
1189
1190                if (ts_gt(adjustment, src->skew_adjust)) {
1191                        src->skew_adjust = zero_ts;
1192                } else {
1193                        src->skew_adjust = ts_sub(src->skew_adjust, adjustment);
1194                }
1195
1196                src->samples_added -= adjustment.ticks;
1197
1198                debug_msg("Playout buffer shift back %d samples.\n", adjustment.ticks);
1199                src->skew = SOURCE_SKEW_NONE;
1200                return SOURCE_SKEW_SLOW;
1201        }
1202
1203        return SOURCE_SKEW_NONE;
1204}
1205
1206static int
1207source_repair(source     *src,
1208              repair_id_t r,
1209              ts_t        fill_ts)
1210{
1211        media_data* fill_md, *prev_md;
1212        ts_t        prev_ts;
1213        uint32_t     success,  prev_len;
1214
1215        /* We repair one unit at a time since it may be all we need */
1216        if (pb_iterator_retreat(src->media_pos) == FALSE) {
1217                /* New packet when source still active, but dry, e.g. new talkspurt */
1218                debug_msg("Repair not possible no previous unit!\n");
1219                return FALSE;
1220        }
1221
1222        pb_iterator_get_at(src->media_pos,
1223                           (u_char**)&prev_md,
1224                           &prev_len,
1225                           &prev_ts);
1226
1227        media_data_create(&fill_md, 1);
1228        repair(r,
1229               src->consec_lost,
1230               src->codec_states,
1231               prev_md,
1232               fill_md->rep[0]);
1233
1234        success = pb_add(src->media,
1235                         (u_char*)fill_md,
1236                         sizeof(media_data),
1237                         fill_ts);
1238
1239        if (success) {
1240                src->consec_lost++;
1241                src->last_repair = fill_ts;
1242                /* Advance to unit we just added */
1243                pb_iterator_advance(src->media_pos);
1244        } else {
1245                /* This should only ever fail at when source changes
1246                 * sample rate in less time than playout buffer
1247                 * timeout.  This should be a very very rare event... 
1248                 */
1249                debug_msg("Repair add data failed (%d).\n", fill_ts.ticks);
1250                media_data_destroy(&fill_md, sizeof(media_data));
1251                src->consec_lost = 0;
1252                return FALSE;
1253        }
1254        return TRUE;
1255}
1256
1257int
1258source_process(session_t *sp,
1259               source            *src,
1260               struct s_mix_info *ms,
1261               int                render_3d,
1262               repair_id_t        repair_type,
1263               ts_t               start_ts,    /* Real-world time           */
1264               ts_t               end_ts)      /* Real-world time + cushion */
1265{
1266        media_data  *md;
1267        coded_unit  *cu;
1268        codec_state *cs;
1269        uint32_t     md_len;
1270        ts_t        playout, step;
1271        int         i, success, hold_repair = 0;
1272        uint16_t     sample_rate, channels;
1273
1274        /* Note: hold_repair is used to stop repair occuring.
1275         * Occasionally, there is a race condition when the playout
1276         * point is recalculated causing overlap, and when playout
1277         * buffer shift occurs in middle of a loss.
1278         */
1279       
1280        source_process_packets(sp, src, start_ts);
1281
1282        /* Split channel coder units up into media units */
1283        if (pb_node_count(src->channel)) {
1284                channel_decoder_decode(src->channel_state,
1285                                       src->channel,
1286                                       src->media,
1287                                       end_ts);
1288        }
1289
1290        while (ts_gt(end_ts, src->next_played) &&
1291               pb_iterator_advance(src->media_pos)) {
1292                pb_iterator_get_at(src->media_pos,
1293                                   (u_char**)&md,
1294                                   &md_len,
1295                                   &playout);
1296                assert(md != NULL);
1297                assert(md_len == sizeof(media_data));
1298               
1299                /* Conditions for repair:                                    */
1300                /* (a) playout point of unit is further away than expected.  */
1301                /* (b) playout does not correspond to new talkspurt (don't   */
1302                /* fill between end of last talkspurt and start of next).    */
1303                /* NB Use post_talkstart_units as talkspurts maybe longer    */
1304                /* than timestamp wrap period and want to repair even if     */
1305                /* timestamps wrap.                                          */
1306                /* (c) not start of a talkspurt.                             */
1307                /* (d) don't have a hold on.                                 */
1308
1309                if (ts_gt(playout, src->next_played) &&
1310                    ((ts_gt(src->next_played, src->talkstart) && ts_gt(playout, src->talkstart)) || src->post_talkstart_units > 100) &&
1311                    hold_repair == 0) {
1312                        /* If repair was successful media_pos is moved,      */
1313                        /* so get data at media_pos again.                   */
1314                        if (source_repair(src, repair_type, src->next_played) == TRUE) {
1315                                debug_msg("Repair % 2d got % 6d exp % 6d talks % 6d\n",
1316                                          src->consec_lost,
1317                                          playout.ticks,
1318                                          src->next_played.ticks,
1319                                          src->talkstart.ticks);
1320                                success = pb_iterator_get_at(src->media_pos,
1321                                                             (u_char**)&md,
1322                                                             &md_len,
1323                                                             &playout);
1324                                assert(success);
1325                                assert(ts_eq(playout, src->next_played));
1326                        } else {
1327                                /* Repair failed for some reason.  Wait a    */
1328                                /* while before re-trying.                   */
1329                                debug_msg("Repair failed unexpectedly\n");
1330                                hold_repair += 2;
1331                        }
1332                } else {
1333                        if (hold_repair > 0) {
1334                                hold_repair --;
1335                        }
1336                        src->consec_lost = 0;
1337                }
1338
1339                if (ts_gt(playout, end_ts)) {
1340                        /* This playout point is after now so stop */
1341                        pb_iterator_retreat(src->media_pos);
1342                        break;
1343                }
1344
1345                for(i = 0; i < md->nrep; i++) {
1346                        if (codec_is_native_coding(md->rep[i]->id)) {
1347                                break;
1348                        }
1349                }
1350
1351                if (i == md->nrep) {
1352                        /* We need to decode this unit, may not have to
1353                         * when repair has been used.
1354                         */
1355#ifdef DEBUG
1356                        for(i = 0; i < md->nrep; i++) {
1357                                /* if there is a native coding this
1358                                 * unit has already been decoded and
1359                                 * this would be bug */
1360                                assert(md->rep[i] != NULL);
1361                                assert(codec_id_is_valid(md->rep[i]->id));
1362                                assert(codec_is_native_coding(md->rep[i]->id) == FALSE);
1363                        }
1364#endif /* DEBUG */
1365                        cu = (coded_unit*)block_alloc(sizeof(coded_unit));
1366                        /* Decode frame */
1367                        assert(cu != NULL);
1368                        memset(cu, 0, sizeof(coded_unit));
1369                        cs = codec_state_store_get(src->codec_states, md->rep[0]->id);
1370                        codec_decode(cs, md->rep[0], cu);
1371                        assert(md->rep[md->nrep] == NULL);
1372                        md->rep[md->nrep] = cu;
1373                        md->nrep++;
1374                }
1375
1376                if (render_3d && src->pdbe->render_3D_data) {
1377                        /* 3d rendering necessary */
1378                        coded_unit *decoded, *render;
1379                        decoded = md->rep[md->nrep - 1];
1380                        assert(codec_is_native_coding(decoded->id));
1381                       
1382                        render = (coded_unit*)block_alloc(sizeof(coded_unit));
1383                        memset(render, 0, sizeof(coded_unit));
1384                       
1385                        render_3D(src->pdbe->render_3D_data,decoded,render);
1386                        assert(md->rep[md->nrep] == NULL);
1387                        md->rep[md->nrep] = render;
1388                        md->nrep++;
1389                }
1390
1391                if (src->converter) {
1392                        /* convert frame */
1393                        coded_unit *decoded, *render;
1394                        decoded = md->rep[md->nrep - 1];
1395                        assert(codec_is_native_coding(decoded->id));
1396
1397                        render = (coded_unit*)block_alloc(sizeof(coded_unit));
1398                        memset(render, 0, sizeof(coded_unit));
1399                        converter_process(src->converter,
1400                                          decoded,
1401                                          render);
1402                        assert(md->rep[md->nrep] == NULL);
1403                        md->rep[md->nrep] = render;
1404                        md->nrep++;
1405                }
1406
1407                if (src->skew != SOURCE_SKEW_NONE &&
1408                    source_skew_adapt(src, md, playout) != SOURCE_SKEW_NONE) {
1409                        /* We have skew and we have adjusted playout buffer  */
1410                        /* timestamps, so re-get unit to get correct         */
1411                        /* timestamp info.                                   */
1412                        pb_iterator_get_at(src->media_pos,
1413                                           (u_char**)&md,
1414                                           &md_len,
1415                                           &playout);
1416                        assert(md != NULL);
1417                        assert(md_len == sizeof(media_data));
1418                }
1419
1420                if (src->pdbe->gain != 1.0 && codec_is_native_coding(md->rep[md->nrep - 1]->id)) {
1421                        audio_scale_buffer((sample*)md->rep[md->nrep - 1]->data,
1422                                           md->rep[md->nrep - 1]->data_len / sizeof(sample),
1423                                           src->pdbe->gain);
1424                }
1425
1426                assert(codec_is_native_coding(md->rep[md->nrep - 1]->id));
1427                codec_get_native_info(md->rep[md->nrep - 1]->id, &sample_rate, &channels);
1428                step = ts_map32(sample_rate, md->rep[md->nrep - 1]->data_len / (channels * sizeof(sample)));
1429                src->next_played = ts_add(playout, step);
1430                src->samples_played += md->rep[md->nrep - 1]->data_len / (channels * sizeof(sample));
1431
1432                if (mix_process(ms, src->pdbe, md->rep[md->nrep - 1], playout) == FALSE) {
1433                        /* Sources sampling rate changed mid-flow? dump data */
1434                        /* make source look irrelevant, it should get        */
1435                        /* destroyed and the recreated with proper decode    */
1436                        /* path when new data arrives.  Not graceful..       */
1437                        /* A better way would be just to flush media then    */
1438                        /* invoke source_reconfigure if this is ever really  */
1439                        /* an issue.                                         */
1440                        pb_flush(src->media);
1441                        pb_flush(src->channel);
1442                }
1443        }
1444
1445        source_update_bps(src, start_ts);
1446
1447        UNUSED(i); /* Except for debugging */
1448       
1449        return TRUE;
1450}
1451
1452int
1453source_audit(source *src)
1454{
1455        if (src->age != 0) {
1456                /* Keep 1/8 seconds worth of audio */
1457                pb_iterator_audit(src->media_pos, history_ts);
1458                return TRUE;
1459        }
1460        return FALSE;
1461}
1462
1463ts_t
1464source_get_audio_buffered (source *src)
1465{
1466        /* Changes in avg_transit change amount of audio buffered. */
1467        /* It's how much transit is off from start.                */
1468        ts_t delta;
1469        delta = ts_sub(src->pdbe->transit, src->pdbe->avg_transit);
1470        return ts_add(src->pdbe->playout, delta);
1471}
1472
1473ts_t
1474source_get_playout_delay (source *src)
1475{
1476        return src->pdbe->playout;
1477}
1478
1479int
1480source_relevant(source *src, ts_t now)
1481{
1482        assert(src);
1483
1484        if (pb_relevant(src->media, now) || pb_relevant(src->channel, now) || src->age < 50) {
1485                return TRUE;
1486        } if (ts_valid(src->next_played)) {
1487                /* Source is quiescent                                     */
1488                ts_t quiet;       
1489                quiet = ts_sub(now, src->next_played);
1490                if (ts_gt(keep_source_ts, quiet)) {
1491                        return TRUE;
1492                }
1493        }
1494        return FALSE;
1495}
1496
1497struct s_pb*
1498source_get_decoded_buffer(source *src)
1499{
1500        return src->media;
1501}
1502
1503uint32_t
1504source_get_ssrc(source *src)
1505{
1506        return src->pdbe->ssrc;
1507}
1508
1509double
1510source_get_skew_rate(source *src)
1511{
1512        if (src->samples_played) {
1513                double r = (double)(src->samples_played + src->samples_added) / (double)src->samples_played;
1514                return r;
1515        }
1516        return 1.0;
1517}
Note: See TracBrowser for help on using the browser.