root/rat/trunk/ui.c @ 2058

Revision 2058, 26.9 KB (checked in by ucaccsp, 16 years ago)

Remove tool.rat.redundancy and tool.rat.interleaving, and merge their
functions into audio.channel.coding

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * FILE:    ui_control.c
3 * PROGRAM: RAT
4 * AUTHOR:  Isidor Kouvelas + Colin Perkins + Orion Hodson
5 *     
6 * This file contains routines which update the user interface. There is no
7 * direct connection between the user interface and the media engine now, all
8 * updates are done via the conference bus.
9 *
10 * Copyright (c) 1995-98 University College London
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, is permitted, for non-commercial use only, provided
15 * that the following conditions are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 *    must display the following acknowledgement:
23 *      This product includes software developed by the Computer Science
24 *      Department at University College London
25 * 4. Neither the name of the University nor of the Department may be used
26 *    to endorse or promote products derived from this software without
27 *    specific prior written permission.
28 * Use of this software for commercial purposes is explicitly forbidden
29 * unless prior written permission is obtained from the authors.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
32 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * SUCH DAMAGE.
42 */
43
44#include "config_unix.h"
45#include "config_win32.h"
46#include "assert.h"
47#include "debug.h"
48#include "memory.h"
49#include "version.h"
50#include "session.h"
51#include "crypt.h"
52#include "rtcp_pckt.h"
53#include "rtcp_db.h"
54#include "repair.h"
55#include "receive.h"
56#include "codec.h"
57#include "convert.h"
58#include "audio.h"
59#include "mbus.h"
60#include "mbus_engine.h"
61#include "channel.h"
62#include "mix.h"
63#include "transmit.h"
64#include "ui.h"
65#include "timers.h"
66
67static char *mbus_name_engine = NULL;
68static char *mbus_name_ui     = NULL;
69static char *mbus_name_video  = NULL;
70
71/*
72 * Update the on screen information for the given participant
73 *
74 * Note: We must be careful, since the Mbus code uses the CNAME
75 *       for communication with the UI. In a few cases we have
76 *       valid state for a participant (ie: we've received an
77 *       RTCP packet for that SSRC), but do NOT know their CNAME.
78 *       (For example, if the first packet we receive from a source
79 *       is an RTCP BYE piggybacked with an empty RR). In those
80 *       cases, we just ignore the request and send nothing to the
81 *       UI. [csp]
82 */
83
84void
85ui_info_update_name(session_struct *sp, rtcp_dbentry *e)
86{
87        char *cname, *name, *args;
88
89        if (e->sentry->cname == NULL) return;
90
91        cname = mbus_encode_str(e->sentry->cname);
92        name  = mbus_encode_str(e->sentry->name);
93        args = (char*)xmalloc(strlen(cname) + strlen(name) + 2);
94       
95        sprintf(args, "%s %s", cname, name);
96        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.name", args, TRUE);
97        xfree(cname);
98        xfree(name);
99        xfree(args);
100}
101
102void
103ui_info_update_cname(session_struct *sp, rtcp_dbentry *e)
104{
105        char *cname;
106       
107        if (e->sentry->cname == NULL) return;
108       
109        cname = mbus_encode_str(e->sentry->cname);
110        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.exists", cname, TRUE);
111        xfree(cname);
112}
113
114void
115ui_info_update_email(session_struct *sp, rtcp_dbentry *e)
116{
117        char *cname, *arg, *args;
118
119        if (e->sentry->cname == NULL) return;
120
121        cname = mbus_encode_str(e->sentry->cname);
122        arg   = mbus_encode_str(e->sentry->email);
123        args = (char*)xmalloc(strlen(cname) + strlen(arg) + 2);
124        sprintf(args, "%s %s", cname, arg);
125        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.email", args, TRUE);
126        xfree(cname);
127        xfree(arg);
128        xfree(args);
129}
130
131void
132ui_info_update_phone(session_struct *sp, rtcp_dbentry *e)
133{
134        char *cname, *arg, *args;
135
136        if (e->sentry->cname == NULL) return;
137
138        cname = mbus_encode_str(e->sentry->cname);
139        arg   = mbus_encode_str(e->sentry->phone);
140        args = (char*)xmalloc(strlen(cname) + strlen(arg) + 2);
141        sprintf(args, "%s %s", cname, arg);
142        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.phone", args, TRUE);
143        xfree(cname);
144        xfree(arg);
145        xfree(args);
146}
147
148void
149ui_info_update_loc(session_struct *sp, rtcp_dbentry *e)
150{
151        char *cname, *arg, *args;
152
153        if (e->sentry->cname == NULL) return;
154
155        cname = mbus_encode_str(e->sentry->cname);
156        arg   = mbus_encode_str(e->sentry->loc);
157        args = (char*)xmalloc(strlen(cname) + strlen(arg) + 2);
158        sprintf(args, "%s %s", cname, arg);
159        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.loc", args, TRUE);
160        xfree(cname);
161        xfree(arg);
162        xfree(args);
163}
164
165void
166ui_info_update_tool(session_struct *sp, rtcp_dbentry *e)
167{
168        char *cname = mbus_encode_str(e->sentry->cname);
169        char *arg   = mbus_encode_str(e->sentry->tool);
170        char *args = (char*)xmalloc(strlen(cname) + strlen(arg) + 2);
171        sprintf(args, "%s %s", cname, arg);
172        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.tool", args, TRUE);
173        xfree(cname);
174        xfree(arg);
175        xfree(args);
176}
177
178void
179ui_info_update_note(session_struct *sp, rtcp_dbentry *e)
180{
181        char *cname = mbus_encode_str(e->sentry->cname);
182        char *arg   = mbus_encode_str(e->sentry->note);
183        char *args = (char*)xmalloc(strlen(cname) + strlen(arg) + 2);
184        sprintf(args, "%s %s", cname, arg);
185        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.note", args, TRUE);
186        xfree(cname);
187        xfree(arg);
188        xfree(args);
189}
190
191void
192ui_info_mute(session_struct *sp, rtcp_dbentry *e)
193{
194        char *cname = mbus_encode_str(e->sentry->cname);
195        char *args = (char*)xmalloc(strlen(cname) + 4);
196        sprintf(args, "%s %2d", cname, e->mute);
197        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.mute", args, TRUE);
198        xfree(cname);
199        xfree(args);
200}
201
202void
203ui_info_remove(session_struct *sp, rtcp_dbentry *e)
204{
205        char *cname;
206       
207        if (e->sentry->cname == NULL) return;
208       
209        cname = mbus_encode_str(e->sentry->cname);
210        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.remove", cname, TRUE);
211        xfree(cname);
212}
213
214void
215ui_info_activate(session_struct *sp, rtcp_dbentry *e)
216{
217        char *cname;
218       
219        if (e->sentry->cname == NULL) return;
220       
221        cname = mbus_encode_str(e->sentry->cname);
222        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.active", cname, FALSE);
223        xfree(cname);
224}
225
226void
227ui_info_deactivate(session_struct *sp, rtcp_dbentry *e)
228{
229        char *cname;
230
231        if (e->sentry->cname == NULL) return;
232       
233        cname = mbus_encode_str(e->sentry->cname);
234        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.inactive", cname, FALSE);
235        xfree(cname);
236}
237
238void
239ui_update_stats(session_struct *sp, rtcp_dbentry *e)
240{
241        char    *my_cname, *their_cname, *args, *mbes;
242        codec_t *pcp;
243
244        if (sp->db->my_dbe->sentry == NULL || sp->db->my_dbe->sentry->cname == NULL) {
245                debug_msg("Warning sentry or name == NULL\n");
246                return;
247        }
248
249        if (e->sentry->cname == NULL) {
250                return;
251        }
252
253        my_cname    = mbus_encode_str(sp->db->my_dbe->sentry->cname);
254        their_cname = mbus_encode_str(e->sentry->cname);
255
256        if (e->enc_fmt) {
257                pcp  = get_codec_by_pt(e->enc);
258                mbes = mbus_encode_str(pcp->short_name);
259                args = (char *) xmalloc(strlen(their_cname) + strlen(mbes) + 2);
260                sprintf(args, "%s %s", their_cname, mbes);
261        } else {
262                args = (char *) xmalloc(strlen(their_cname) + 7 + 2);
263                sprintf(args, "%s unknown", their_cname);
264        }
265        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.codec", args, FALSE);
266        xfree(args);
267
268        /* args size is for source.packet.loss, tool.rat.audio.buffered size always less */
269        args = (char *) xmalloc(strlen(their_cname) + strlen(my_cname) + 11);
270       
271        sprintf(args, "%s %ld", their_cname, playout_buffer_duration(sp->playout_buf_list, e));
272        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.audio.buffered", args, FALSE);
273
274        sprintf(args, "%s %s %8ld", my_cname, their_cname, (e->lost_frac * 100) >> 8);
275        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.packet.loss", args, FALSE);
276
277        xfree(my_cname);
278        xfree(their_cname);
279        xfree(args);
280}
281
282void
283ui_update_input_port(session_struct *sp)
284{
285        switch (sp->input_mode) {
286        case AUDIO_MICROPHONE:
287                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.input.port", "microphone", TRUE);
288                break;
289        case AUDIO_LINE_IN:
290                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.input.port", "line_in", TRUE);
291                break
292        case AUDIO_CD:
293                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.input.port", "cd", TRUE);
294                break;
295        default:
296                fprintf(stderr, "Invalid input port!\n");
297                return ;
298        }
299        if (sp->sending_audio) {
300                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.input.mute", "0", TRUE);
301        } else {
302                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.input.mute", "1", TRUE);
303        }
304}
305
306void
307ui_update_output_port(session_struct *sp)
308{
309        switch (sp->output_mode) {
310        case AUDIO_SPEAKER:
311                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.port", "speaker", TRUE);
312                break;
313        case AUDIO_HEADPHONE:
314                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.port", "headphone", TRUE);
315                break;
316        case AUDIO_LINE_OUT:
317                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.port", "line_out", TRUE);
318                break;
319        default:
320                fprintf(stderr, "Invalid output port!\n");
321                return;
322        }
323        if (sp->playing_audio) {
324                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.mute", "0", TRUE);
325        } else {
326                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.mute", "1", TRUE);
327        }
328}
329
330void
331ui_input_level(session_struct *sp, int level)
332{
333        static int      ol;
334        char            args[4];
335
336        assert(level>=0 && level <=100);
337
338        if (ol == level) {
339                return;
340        }
341
342        sprintf(args, "%3d", level);
343        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.input.powermeter", args, FALSE);
344        ol = level;
345}
346
347void
348ui_output_level(session_struct *sp, int level)
349{
350        static int      ol;
351        char            args[4];
352        assert(level>=0 && level <=100);
353
354        if (ol == level) {
355                return;
356        }
357
358        sprintf(args, "%3d", level);
359        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.powermeter", args, FALSE);
360        ol = level;
361}
362
363static void
364ui_repair(session_struct *sp)
365{
366        char    *repair = NULL;
367
368        switch(sp->repair) {
369        case REPAIR_NONE:
370                repair = mbus_encode_str("none");
371                break;
372        case REPAIR_REPEAT:
373                repair = mbus_encode_str("repetition");
374                break;
375        case REPAIR_PATTERN_MATCH:
376                repair = mbus_encode_str("pattern-match");
377                break;
378        }
379        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.channel.repair", repair, FALSE);
380        xfree(repair);
381}
382
383void
384ui_update_frequency(session_struct *sp)
385{
386        codec_t *pcp;
387        char     args[7], *mbes;
388
389        pcp = get_codec_by_pt(sp->encodings[0]);
390        sprintf(args, "%d-kHz", pcp->freq/1000);
391        assert(strlen(args) < 7);
392        mbes = mbus_encode_str(args);
393        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.frequency", mbes, FALSE);
394        xfree(mbes);
395}
396
397void
398ui_update_channels(session_struct *sp)
399{
400        codec_t *pcp;
401        char    *mbes;
402       
403        pcp = get_codec_by_pt(sp->encodings[0]);
404        switch(pcp->channels) {
405        case 1:
406                mbes = mbus_encode_str("Mono");
407                break;
408        case 2:
409                mbes = mbus_encode_str("Stereo");
410                break;
411        default:
412                debug_msg("UI not ready for %d channels\n", pcp->channels);
413                return;
414        }
415        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.channels", mbes, FALSE);
416        xfree(mbes);
417}       
418
419void
420ui_update_primary(session_struct *sp)
421{
422        codec_t *pcp;
423        char *mbes;
424
425        pcp = get_codec_by_pt(sp->encodings[0]);
426        mbes = mbus_encode_str(pcp->short_name);
427        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.codec", mbes, FALSE);
428        xfree(mbes);
429}
430
431static void
432ui_update_interleaving(session_struct *sp)
433{
434        int pt, isep, iu;
435        char buf[128], *sep=NULL, *units = NULL, *dummy, args[80];
436
437        pt = get_cc_pt(sp,"INTERLEAVER");
438        if (pt != -1) {
439                query_channel_coder(sp, pt, buf, 128);
440                dummy  = strtok(buf,"/");
441                units  = strtok(NULL,"/");
442                sep    = strtok(NULL,"/");
443        } else {
444                debug_msg("Could not find interleaving channel coder!\n");
445        }
446       
447        if (units != NULL && sep != NULL) {
448                iu   = atoi(units);
449                isep = atoi(sep);
450        } else {
451                iu   = 4;
452                isep = 4;
453        }
454
455        sprintf(args,"\"interleaved\" %d %d",iu, isep);
456        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.channel.coding", args, TRUE);       
457}
458
459static void
460ui_update_redundancy(session_struct *sp)
461{
462        int  pt;
463        int  ioff;
464        char buf[128]= "", *codec_name=NULL, *offset=NULL, *dummy, *args;
465
466        pt = get_cc_pt(sp,"REDUNDANCY");
467        if (pt != -1) {
468                codec_t *cp;
469                query_channel_coder(sp, pt, buf, 128);
470                if (strlen(buf)) {
471                        dummy  = strtok(buf,"/");
472                        dummy  = strtok(NULL,"/");
473                        codec_name  = strtok(NULL,"/");
474                        /* redundant coder returns long name convert to short*/
475                        if (codec_name) {
476                                cp         = get_codec_by_name(codec_name);
477                                assert(cp);
478                                codec_name = cp->short_name;
479                        }
480                        offset = strtok(NULL,"/");
481                }
482        } else {
483                debug_msg("Could not find redundant channel coder!\n");
484        }
485
486        if (codec_name != NULL && offset != NULL) {
487                ioff  = atoi(offset);
488        } else {
489                codec_t *pcp;
490                pcp   = get_codec_by_pt(sp->encodings[0]);
491                codec_name = pcp->short_name;
492                ioff  = 1;
493        }
494
495        codec_name = mbus_encode_str(codec_name);
496
497        args = (char *) xmalloc(strlen(codec_name) + 16);
498        sprintf(args,"\"redundant\" %s %2d", codec_name, ioff);
499        assert(strlen(args) < (strlen(codec_name) + 16));
500        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.channel.coding", args, TRUE);
501        xfree(codec_name);
502        xfree(args);
503}
504
505void 
506ui_update_channel(session_struct *sp)
507{
508        cc_coder_t *ccp;
509
510        ccp = get_channel_coder(sp->cc_encoding);
511        if (strcmp(ccp->name, "VANILLA") == 0) {
512                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.channel.coding", "\"none\"", TRUE);
513        } else if (strcmp(ccp->name, "REDUNDANCY") == 0) {
514                ui_update_redundancy(sp);
515        } else if (strcmp(ccp->name, "INTERLEAVER") == 0) {
516                ui_update_interleaving(sp);
517        } else {
518                debug_msg("Channel coding failed mapping (%s)\n", ccp->name);
519                abort();
520        }
521}
522
523void
524ui_update_input_gain(session_struct *sp)
525{
526        char    args[4];
527
528        sprintf(args, "%3d", audio_get_gain(sp->audio_device));
529        assert(strlen(args) < 4);
530        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.input.gain", args, TRUE);
531}
532
533void
534ui_update_output_gain(session_struct *sp)
535{
536        char    args[4];
537
538        sprintf(args, "%3d", audio_get_volume(sp->audio_device));
539        assert(strlen(args) < 4);
540        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.gain", args, TRUE);
541}
542
543static void
544ui_devices(session_struct *sp)
545{
546        int i,nDev;
547        char buf[255] = "", *this_dev, *mbes;
548       
549        nDev = audio_get_number_of_interfaces();
550        for(i = 0; i < nDev; i++) {
551                this_dev = audio_get_interface_name(i);
552                if (this_dev) {
553                        strcat(buf, this_dev);
554                        strcat(buf, ",");
555                }
556        }
557        i = strlen(buf);
558        if (i != 0) buf[i-1] = '\0';
559
560        mbes = mbus_encode_str(buf);
561        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.devices", mbes, TRUE);
562        xfree(mbes);
563}
564
565static void
566ui_device(session_struct *sp)
567{
568        char *mbes, *cur_dev;
569        cur_dev = audio_get_interface_name(audio_get_interface());
570
571        if (cur_dev) {
572                mbes = mbus_encode_str(cur_dev);
573                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.device", mbes, TRUE);
574                xfree(mbes);
575        }
576}
577
578void
579ui_update(session_struct *sp)
580{
581        static   int    done=0;
582        char            args[4];
583
584        /*XXX solaris seems to give a different volume back to what we   */
585        /*    actually set.  So don't even ask if it's not the first time*/
586        if (done==0) {
587                ui_update_input_gain(sp);
588                ui_update_output_gain(sp);
589                done=1;
590        } else {
591                sprintf(args, "%3d", sp->output_gain); mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.output.gain", args, TRUE);
592                assert(strlen(args) < 4);
593                sprintf(args, "%3d", sp->input_gain ); mbus_qmsg(sp->mbus_engine_base, mbus_name_ui,  "audio.input.gain", args, TRUE);
594                assert(strlen(args) < 4);
595        }
596
597        sprintf(args, "%3d", collator_get_units(sp->collator));
598        assert(strlen(args) < 4);
599        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.rate", args, TRUE);
600
601        ui_update_output_port(sp);
602        ui_update_input_port(sp);
603        ui_codecs(sp, sp->encodings[0]);
604        ui_devices(sp);
605        ui_device(sp);
606        ui_sampling_modes(sp);
607        ui_converters(sp);
608        ui_update_frequency(sp);
609        ui_update_channels(sp);
610        ui_update_primary(sp);
611        ui_update_channel(sp);
612        ui_repair(sp);
613}
614
615void
616ui_show_audio_busy(session_struct *sp)
617{
618        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.disable.audio.ctls", "", TRUE);
619}
620
621void
622ui_hide_audio_busy(session_struct *sp)
623{
624        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.enable.audio.ctls", "", TRUE);
625}
626
627
628void
629ui_update_lecture_mode(session_struct *sp)
630{
631        /* Update the UI to reflect the lecture mode setting...*/
632        char    args[2];
633        sprintf(args, "%1d", sp->lecture);
634        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.lecture.mode", args, TRUE);
635}
636
637void
638ui_update_powermeters(session_struct *sp, struct s_mix_info *ms, int elapsed_time)
639{
640        static u_int32 power_time = 0;
641
642        if (power_time > sp->meter_period) {
643                if (sp->meter && (ms != NULL)) {
644                        mix_update_ui(sp, ms);
645                }
646                if (sp->sending_audio) {
647                        tx_update_ui(sp);
648                }
649                power_time = 0;
650        } else {
651                power_time += elapsed_time;
652        }
653}
654
655void
656ui_update_loss(session_struct *sp, char *srce, char *dest, int loss)
657{
658        char    *srce_e, *dest_e, *args;
659
660        if ((srce == NULL) || (dest == NULL)) {
661                return;
662        }
663
664        srce_e = mbus_encode_str(srce);
665        dest_e = mbus_encode_str(dest);
666        args   = (char *) xmalloc(strlen(srce_e) + strlen(dest_e) + 6);
667        sprintf(args, "%s %s %3d", srce_e, dest_e, loss);
668        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.packet.loss", args, FALSE);
669        xfree(args);
670        xfree(srce_e);
671        xfree(dest_e);
672}
673
674void
675ui_update_reception(session_struct *sp, char *cname, u_int32 recv, u_int32 lost, u_int32 misordered, u_int32 duplicates, u_int32 jitter, int jit_tog)
676{
677        char    *cname_e, *args;
678
679        if (cname == NULL) return;
680
681        cname_e = mbus_encode_str(cname);
682
683        /* I hate this function! */
684        args = (char *) xmalloc(strlen(cname_e) + 88);
685        sprintf(args, "%s %6ld %6ld %6ld %6ld %6ld %6d", cname_e, recv, lost, misordered, duplicates, jitter, jit_tog);
686        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.reception", args, FALSE);
687        xfree(args);
688        xfree(cname_e);
689}
690
691void
692ui_update_duration(session_struct *sp, char *cname, int duration)
693{
694        char    *cname_e, *args;
695
696        if (cname == NULL) return;
697
698        cname_e = mbus_encode_str(cname);
699        args    = (char *) xmalloc(5 + strlen(cname_e));
700
701        sprintf(args, "%s %3d", cname_e, duration);
702        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.source.packet.duration", args, FALSE);
703        xfree(args);
704        xfree(cname_e);
705}
706
707void 
708ui_update_video_playout(session_struct *sp, char *cname, int playout)
709{
710        char    *cname_e, *args;
711
712        if (cname == NULL) return;
713
714        cname_e = mbus_encode_str(cname);
715        args    = (char *) xmalloc(14 + strlen(cname_e));
716
717        sprintf(args, "%s %12d", cname_e, playout);
718        mbus_qmsg(sp->mbus_engine_base, mbus_name_video, "source_playout", args, FALSE);
719        xfree(args);
720        xfree(cname_e);
721}
722
723void   
724ui_update_sync(session_struct *sp, int sync)
725{
726        if (sync) {
727                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.sync", "1", TRUE);
728        } else {
729                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.sync", "0", TRUE);
730        }
731}
732
733void
734ui_update_key(session_struct *sp, char *key)
735{
736        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "security.encryption.key", key, TRUE);
737}
738
739static int
740codec_bw_cmp(const void *a, const void *b)
741{
742        int bwa, bwb;
743        bwa = (*((codec_t**)a))->max_unit_sz;
744        bwb = (*((codec_t**)b))->max_unit_sz;
745        if (bwa<bwb) {
746                return 1;
747        } else if (bwa>bwb) {
748                return -1;
749        }
750        return 0;
751}
752
753static char *
754ui_get_codecs(int pt, char *buf, unsigned int buf_len, int loose)
755{
756        codec_t *codec[10],*sel;
757        u_int32  i,nc, cnt;
758        char *bp = buf;
759       
760        cnt = get_codec_count();
761        sel = get_codec_by_pt(pt);
762       
763        for (nc = i = 0; i< cnt ; i++) {
764                codec[nc] = get_codec_by_index(i);
765                if (codec[nc] != NULL && codec[nc]->encode != NULL) {
766                        if (loose == TRUE && codec_loosely_compatible(sel,codec[nc])) {
767                                /* Picking out primary codecs, i.e. not bothered
768                                 * about sample size and block sizes matching.
769                                 */
770                                nc++;
771                                assert(nc<10);
772                        } else if (codec_compatible(sel, codec[nc])) {
773                                /* Picking out redundant codecs where we are
774                                 * fussed about sample and block size matching.
775                                 */
776                                nc++;
777                                assert(nc<10);
778                        }
779                }
780        }
781       
782        /* sort by bw as this makes handling of acceptable redundant codecs easier in ui */
783        qsort(codec,nc,sizeof(codec_t*),codec_bw_cmp);
784        for(i=0;i<nc && strlen(buf) + strlen(codec[i]->short_name) < buf_len;i++) {
785                sprintf(bp, "%s ", codec[i]->short_name);
786                bp += strlen(codec[i]->short_name) + 1;
787        }
788
789        if (i != nc) {
790                debug_msg("Ran out of buffer space.\n");
791        }
792       
793        if (bp != buf) *(bp-1) = 0;
794        return buf;
795}
796
797void
798ui_update_playback_file(session_struct *sp, char *name)
799{
800        char *mbes;
801        mbes = mbus_encode_str(name);
802        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.file.play.ready", mbes, TRUE);
803        xfree(mbes);
804}
805
806void
807ui_update_record_file(session_struct *sp, char *name)
808{
809        char *mbes;
810        mbes = mbus_encode_str(name);
811        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "audio.file.record.ready", mbes, TRUE);
812        xfree(mbes);
813}
814
815void
816ui_update_file_live(session_struct *sp, char *mode, int valid)
817{
818        char cmd[32], arg[2];
819       
820        assert(!strcmp(mode, "play") || !strcmp(mode, "record"));
821       
822        sprintf(cmd, "audio.file.%s.alive", mode);
823        sprintf(arg, "%1d", valid);
824        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, cmd, arg, TRUE);
825}
826
827void 
828ui_codecs(session_struct *sp, int pt)
829{
830        char    args[256], *mbes;       /* Hope that's big enough... :-) */
831
832        ui_get_codecs(pt, args, 256, TRUE);
833        mbes = mbus_encode_str(args);
834        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.codec.supported", mbes, TRUE);
835        xfree(mbes);
836        ui_get_codecs(pt, args, 256, FALSE);
837        mbes = mbus_encode_str(args);
838        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.redundancy.supported", mbes, TRUE);
839        xfree(mbes);
840}
841
842void 
843ui_converters(session_struct *sp)
844{
845        char buf[255], *mbes;
846        if (converter_get_names(buf, 255)) {
847                mbes = mbus_encode_str(buf);
848                mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.converter.supported", mbes, TRUE);
849                xfree(mbes);
850        }
851}
852
853void
854ui_sampling_modes(session_struct *sp)
855{
856        char    *mbes;
857        char    modes[255]="";
858        char    tmp[22];
859        u_int16 rate, channels, support, zap;
860       
861        for(rate = 8000; rate <=48000; rate += 8000) {
862                support = 0;
863                for(channels = 1; channels <= 2; channels++) {
864                        if (audio_device_supports(sp->audio_device, rate, channels)) support += channels;
865                }
866                switch(support) {
867                case 3: sprintf(tmp, "%d-kHz,Mono,Stereo ", rate/1000); break;
868                case 2: sprintf(tmp, "%d-kHz,Stereo ", rate/1000);      break;
869                case 1: sprintf(tmp, "%d-kHz,Mono ", rate/1000);        break;
870                case 0: continue;
871                }
872                strcat(modes, tmp);
873        }
874
875        debug_msg("Sampling modes: %s\n", modes);
876
877        /* Remove trailing space */
878        zap = strlen(modes);
879        if (zap) {
880                zap -= 1;
881                modes[zap] = '\0';
882        }
883
884        mbes = mbus_encode_str(modes);
885        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.sampling.supported", mbes, TRUE);
886        xfree(mbes);
887}
888
889void
890ui_controller_init(session_struct *sp, char *cname, char *name_engine, char *name_ui, char *name_video)
891{
892        char    *my_cname;
893
894        mbus_name_engine = name_engine;
895        mbus_name_ui     = name_ui;
896        mbus_name_video  = name_video;
897
898        my_cname = mbus_encode_str(cname);
899        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "rtp.cname", my_cname, TRUE);
900        xfree(my_cname);
901}
902
903void
904ui_title(session_struct *sp)
905{
906        char    *addr, *args, *title;
907
908        title = mbus_encode_str(sp->title);
909        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "session.title", title, TRUE);
910        xfree(title);
911
912        addr = mbus_encode_str(sp->asc_address);
913        args = (char *) xmalloc(strlen(addr) + 11);
914        sprintf(args, "%s %5d %3d", addr, sp->rtp_port, sp->ttl);
915        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "session.address", args, TRUE);
916        xfree(args);
917        xfree(addr);
918}
919
920void
921ui_load_settings(session_struct *sp)
922{
923        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "tool.rat.load.settings", "", TRUE);
924}
925
926void 
927ui_quit(session_struct *sp)
928{
929        mbus_qmsg(sp->mbus_engine_base, mbus_name_ui, "mbus.quit", "", TRUE);
930}
931
932
933
Note: See TracBrowser for help on using the browser.